如果文本包含在字符串列表中,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 分析器并测量真正的瓶颈所在,并确定最适合您的特定场景的方法。

无论您决定使用什么重要的解决方案,请记住,下一个维护您代码的人可能知道您住在哪里。