我有这个foreach循环以正确的顺序替换字符串中的字符,但它会慢...
输入字符串可以有不同的长度.. 字符串长度范围1000 - 1000000
每个char查找只需要1.2毫秒..
但是输入字符串会降低速度,无论如何要更快地替换字符..
charlist只是char替换..
我正在使用charlist项目中的input
替换value2
字符串中的字符..
List<CharItem> charlist; //Charlist count = 98..
var txxt = input.ToCharArray();
string test = "";
foreach (var itm in txxt)
{
var itm2 = (from x in charlist where x.Value == itm select x).FirstOrDefault();
if (itm2 != null)
test = test + itm2.Value2;
}
public class CharItem
{
public char Value { get; set; }
public char Value2 { get; set; }
public override string ToString()
{
return "1." + Value + "| 2." + Value2;
}
}
至于这句话test = test + itm2.Value2;
我不认为字符串构建者更快......
无论如何要加快速度,但是char命令需要相同,只需更换.. 我知道我的硬件速度有限,只是优化我的代码..
答案 0 :(得分:1)
这里有两个问题:
所以我建议使用此代码:
List<CharItem> charlist; //Charlist count = 98..
var replacementRule = charlist.ToDictionary(item => item.Value, item => item.Value2);
char tempC;
return new string(input
.Select(c => replacementRule.TryGetValue(c, out tempC) ? tempC : (char?) null)
.Where(c => c != null)
.Select(c => (char)c)
.ToArray()
);
第二种方式是:
var sb = new StringBuilder();;
foreach (var c in input)
{
char tempC;
if (replacementRule.TryGetValue(c, out tempC))
{
sb.Append(tempC);
}
}
return sb.ToString();
这里是并行LINQ简单并行化的第三个:
const int batchCount = 8; // ~ logical processor count
var batchSize = (input.Length - 1) / batchCount + 1);
var result = Enumerable
.Range(0, batchCount)
.Select(
ind => new
{
Index = ind,
StringPart = input.Substring(
Math.Min(input.Length, batchSize * ind),
Math.Min(batchSize, input.Length - Math.Min(input.Length, batchSize * ind))
)
})
.AsParallel()
.Select(
batch => new
{
batch.Index,
Result = ReplaceInBatch(replacementRule, batch.StringPart)
})
.OrderBy(batch => batch.Index)
.Aggregate(new StringBuilder(input.Length), (sb, batch) => sb.Append(batch.Result))
.ToString();
// ....
// somewhere
private static StringBuilder ReplaceInBatch(IReadOnlyDictionary<char, char> replacementRule, string batch)
{
var sb = new StringBuilder();
foreach (var c in batch)
{
char tempC;
if (replacementRule.TryGetValue(c, out tempC))
{
sb.Append(tempC);
}
}
return sb;
}
完整的测试控制台应用。它用小写字母替换小写字母:link
两种方式都有两个版本 - 差异可以在这里找到:link
并行方式的第三次修订。
答案 1 :(得分:0)
您可以尝试以下操作:
var charlist = Enumerable.Range(50, 10)
.Select(x => new CharItem { Value = (char)x, Value2 = (char)(x + 1) }).ToList();
// charlist = { [1.2| 2.3], [1.3| 2.4], ... [1.9| 2.:], [1.:| 2.;], [1.;| 2.<] }
var dict = charlist.ToDictionary(x => x.Value, x => x.Value2);
new string("12345".Select(x => dict.ContainsKey(x) ? dict[x] : x).ToArray())
// "13456"