如果文本包含在字符串列表中,C# 将字符串中的文本替换为
C# Replace a text in string with if the text contains in String list
我正在尝试用 Dictionary Value 替换字符串中的文本,前提是它与 Dictionary Key 匹配。
Select * 来自 Table1,其中 column1 ={Value1} 和 Column2 = {value2}。
mydict.Add({value1},OriginalValue1);
mydict.Add({value2},OriginalValue2);
我可以遍历字典键并替换字符串中的文本,但如果字典对象中的项目超过 100 个,这将影响性能。
foreach(string key in mydict.keys)
{
if(Query.Contains(key)
{
//Replace the string
}
有没有一种方法可以在对性能影响最小的情况下实现这一点?
只是速度和字典性能的一个例子。这是 4 岁 i7-3820 上的一个线程
- 在时间 0ms
中找到字符串 "some 11998948 input" 中的 1
- 在时间 0ms
中在字符串 "some 11998948 input" 中找到 4
- 在 1ms
的时间内找到字符串 "some 11998948 input" 中的 8 个
- 在 1ms
的时间内在字符串 "some 11998948 input" 中找到了 9
- 在 1ms
的时间内在字符串 "some 11998948 input" 中找到了 11
- 在 1ms
的时间内在字符串 "some 11998948 input" 中找到了 19
- 在 1ms
的时间内在字符串 "some 11998948 input" 中找到了 48
- 在 1ms
的时间内找到字符串 "some 11998948 input" 中的 89
- 在 1ms
的时间内在字符串 "some 11998948 input" 中找到了 94
- 在 1ms 的时间内在字符串 "some 11998948 input" 中找到 98
- 在 1ms
的时间内在字符串 "some 11998948 input" 中找到了 99
- 在 1ms
的时间内找到字符串 "some 11998948 input" 中的 119
- 在 1ms
的时间内在字符串 "some 11998948 input" 中找到 199
- 在 1ms
的时间内在字符串 "some 11998948 input" 中找到 894
- 在 2ms
的时间内在字符串 "some 11998948 input" 中找到 948
- 在 2ms
的时间内在字符串 "some 11998948 input" 中找到了 989
- 在 2ms
的时间内在字符串 "some 11998948 input" 中找到了 998
- 在 2ms
的时间内在字符串 "some 11998948 input" 中找到 1199
- 在字符串 "some 11998948 input" 中找到 1998,时间为 2ms
- 在 3ms
的时间内在字符串 "some 11998948 input" 中找到了 8948
- 在 3ms
的时间内在字符串 "some 11998948 input" 中找到 9894
- 在 3ms
的时间内在字符串 "some 11998948 input" 中找到 9989
- 在 4ms
的时间内在字符串 "some 11998948 input" 中找到 11998
- 在字符串"some 11998948 input"中找到19989,耗时5ms
- 在 21ms
的时间内在字符串 "some 11998948 input" 中找到了 98948
- 在 21ms
的时间内在字符串 "some 11998948 input" 中找到了 99894
- 在 25ms
的时间内在字符串 "some 11998948 input" 中找到了 119989
- 在字符串"some 11998948 input"中找到199894,耗时42ms
- 在时间 214ms
中找到字符串 "some 11998948 input" 中的 998948
- 在时间 255ms
中找到字符串 "some 11998948 input" 中的 1199894
- 在时间 400ms
中找到字符串 "some 11998948 input" 中的 1998948
- 在时间 2127ms
中找到字符串 "some 11998948 input" 中的 11998948
这意味着遍历约 1200 万个元素大约需要 2 秒。字典不是你的问题。 (但我认为可能是部分匹配)
我用这个代码 运行 它。
Dictionary<string, string> dic = new Dictionary<string, string>();
for (int i = 0; i < 11998949; i++) //11998949 is max supported range
{
dic.Add(i.ToString(), i.ToString());
}
Stopwatch sw = new Stopwatch();
sw.Start();
string Query = "some 11998948 input";
foreach(var a in dic.Where(a=> Query.Contains(a.Key)))
{
Console.WriteLine($"Found {a.Key} in string {Query} in time {sw.ElapsedMilliseconds}ms");
}
Console.ReadKey();
首先警告:在你知道你确实有性能问题之前,不要为了优化而使事情复杂化。 100 次替换对我来说听起来没什么大不了的。通常代码的可读性和花在解决实际问题上的时间比节省 10ns 的时间更有价值。
假设每一纳秒都非常重要,那么您应该衡量您的基线并考虑改进方案:
- 从
String.Replace()
等内置简单工具开始。它们在内部通常比您自己做的更优化(除非您知道对输入或所需行为的一些重要的额外限制)
- 不要在替换之前执行额外的
Contains(key)
,因为无论如何您都需要搜索替换的确切位置。或者如果您选择处理索引,请重复使用第一遍,例如使用 String.IndexOf(..)
)。
- 如果您的密钥具有相似的可识别模式(例如:"Key1"、"Key2" 等),那么也许您可以使用已编译的 Regex 替换工具一次性完成所有替换?
- 输入查询是否已修复?
StringBuilder.Append()
可能比 100 倍搜索和替换要快。
- 如果需要迭代所有对,为什么要使用字典?跳过散列魔术和堆中的额外对象并循环简单的键值对。并不是说您会感觉到性能有显着差异..
再次 - 测量!使用 .net 分析器并测量真正的瓶颈所在,并确定最适合您的特定场景的方法。
无论您决定使用什么重要的解决方案,请记住,下一个维护您代码的人可能知道您住在哪里。
我正在尝试用 Dictionary Value 替换字符串中的文本,前提是它与 Dictionary Key 匹配。 Select * 来自 Table1,其中 column1 ={Value1} 和 Column2 = {value2}。
mydict.Add({value1},OriginalValue1);
mydict.Add({value2},OriginalValue2);
我可以遍历字典键并替换字符串中的文本,但如果字典对象中的项目超过 100 个,这将影响性能。
foreach(string key in mydict.keys)
{
if(Query.Contains(key)
{
//Replace the string
}
有没有一种方法可以在对性能影响最小的情况下实现这一点?
只是速度和字典性能的一个例子。这是 4 岁 i7-3820 上的一个线程
- 在时间 0ms 中找到字符串 "some 11998948 input" 中的 1
- 在时间 0ms 中在字符串 "some 11998948 input" 中找到 4
- 在 1ms 的时间内找到字符串 "some 11998948 input" 中的 8 个
- 在 1ms 的时间内在字符串 "some 11998948 input" 中找到了 9
- 在 1ms 的时间内在字符串 "some 11998948 input" 中找到了 11
- 在 1ms 的时间内在字符串 "some 11998948 input" 中找到了 19
- 在 1ms 的时间内在字符串 "some 11998948 input" 中找到了 48
- 在 1ms 的时间内找到字符串 "some 11998948 input" 中的 89
- 在 1ms 的时间内在字符串 "some 11998948 input" 中找到了 94
- 在 1ms 的时间内在字符串 "some 11998948 input" 中找到 98
- 在 1ms 的时间内在字符串 "some 11998948 input" 中找到了 99
- 在 1ms 的时间内找到字符串 "some 11998948 input" 中的 119
- 在 1ms 的时间内在字符串 "some 11998948 input" 中找到 199
- 在 1ms 的时间内在字符串 "some 11998948 input" 中找到 894
- 在 2ms 的时间内在字符串 "some 11998948 input" 中找到 948
- 在 2ms 的时间内在字符串 "some 11998948 input" 中找到了 989
- 在 2ms 的时间内在字符串 "some 11998948 input" 中找到了 998
- 在 2ms 的时间内在字符串 "some 11998948 input" 中找到 1199
- 在字符串 "some 11998948 input" 中找到 1998,时间为 2ms
- 在 3ms 的时间内在字符串 "some 11998948 input" 中找到了 8948
- 在 3ms 的时间内在字符串 "some 11998948 input" 中找到 9894
- 在 3ms 的时间内在字符串 "some 11998948 input" 中找到 9989
- 在 4ms 的时间内在字符串 "some 11998948 input" 中找到 11998
- 在字符串"some 11998948 input"中找到19989,耗时5ms
- 在 21ms 的时间内在字符串 "some 11998948 input" 中找到了 98948
- 在 21ms 的时间内在字符串 "some 11998948 input" 中找到了 99894
- 在 25ms 的时间内在字符串 "some 11998948 input" 中找到了 119989
- 在字符串"some 11998948 input"中找到199894,耗时42ms
- 在时间 214ms 中找到字符串 "some 11998948 input" 中的 998948
- 在时间 255ms 中找到字符串 "some 11998948 input" 中的 1199894
- 在时间 400ms 中找到字符串 "some 11998948 input" 中的 1998948
- 在时间 2127ms 中找到字符串 "some 11998948 input" 中的 11998948
这意味着遍历约 1200 万个元素大约需要 2 秒。字典不是你的问题。 (但我认为可能是部分匹配)
我用这个代码 运行 它。
Dictionary<string, string> dic = new Dictionary<string, string>();
for (int i = 0; i < 11998949; i++) //11998949 is max supported range
{
dic.Add(i.ToString(), i.ToString());
}
Stopwatch sw = new Stopwatch();
sw.Start();
string Query = "some 11998948 input";
foreach(var a in dic.Where(a=> Query.Contains(a.Key)))
{
Console.WriteLine($"Found {a.Key} in string {Query} in time {sw.ElapsedMilliseconds}ms");
}
Console.ReadKey();
首先警告:在你知道你确实有性能问题之前,不要为了优化而使事情复杂化。 100 次替换对我来说听起来没什么大不了的。通常代码的可读性和花在解决实际问题上的时间比节省 10ns 的时间更有价值。
假设每一纳秒都非常重要,那么您应该衡量您的基线并考虑改进方案:
- 从
String.Replace()
等内置简单工具开始。它们在内部通常比您自己做的更优化(除非您知道对输入或所需行为的一些重要的额外限制) - 不要在替换之前执行额外的
Contains(key)
,因为无论如何您都需要搜索替换的确切位置。或者如果您选择处理索引,请重复使用第一遍,例如使用String.IndexOf(..)
)。 - 如果您的密钥具有相似的可识别模式(例如:"Key1"、"Key2" 等),那么也许您可以使用已编译的 Regex 替换工具一次性完成所有替换?
- 输入查询是否已修复?
StringBuilder.Append()
可能比 100 倍搜索和替换要快。 - 如果需要迭代所有对,为什么要使用字典?跳过散列魔术和堆中的额外对象并循环简单的键值对。并不是说您会感觉到性能有显着差异..
再次 - 测量!使用 .net 分析器并测量真正的瓶颈所在,并确定最适合您的特定场景的方法。
无论您决定使用什么重要的解决方案,请记住,下一个维护您代码的人可能知道您住在哪里。