2016-05-12 111 views
0

我想用字典值替换字符串中的文本,如果它与字典键匹配。 从Table1中选择*,其中column1 = {Value1}和Column2 = {value2}。C#用字符串替换文本,如果文本包含在字符串列表中

mydict.Add({value1},OriginalValue1); 
mydict.Add({value2},OriginalValue2); 

我可以通过字典键迭代和替换像字符串中的文本,但是这会影响性能,如果有在Dictionary对象超过100个项目。

foreach(string key in mydict.keys) 
{ 
if(Query.Contains(key) 
{ 
//Replace the string 
} 

有没有办法实现这一点,但对性能影响最小?

+1

是什么让你觉得它会对性能产生足够大的影响? 'Dictionary'类是FAST。 –

+0

如果您的字典中包含“将a更改为b”和“将b更改为a”,那么当字典适用于“ab”时,您会发现什么?输出“ba”还是“aa”? – Gqqnbig

+0

实际上,字典的使用不应该有太大的区别,因为OP正在循环所有的密钥。搜索特定键时字典速度很快。 –

回答

1

首先警告:不要让事情复杂化,希望在知道自己实际上存在性能问题之前进行优化。 100个替代品对我来说听起来不是什么大不了的事。通常代码可读性和花费在解决实际问题上的时间比节省10ns的代价更大。

假设每纳秒真的,真的很重要,那么你应该测量你的基线,并考虑选择改进:与

  • 开始内置样String.Replace()简单的工具。它们在内部通常更加优化比你可以做你自己(除非你知道在输入或期望的行为的一些重要的额外限制)
  • ,因为你需要寻找替代反正确切位置不更换前做多余的Contains(key) 。或者,如果您选择处理索引,则可重复使用第一遍,如使用String.IndexOf(..))。
  • 如果你的钥匙具有类似的可识别图案(例如:“钥匙1”,“钥匙2”等),那么也许你可以使用编译的Regex替换工具一次完成所有替换工作?
  • 输入查询是否可能修复? StringBuilder.Append()大概要比100x搜索&更快。
  • 为什么使用字典,如果你需要迭代所有对?在堆中跳过散列魔法和额外的对象,并在简单的键值对上循环。并不是说你会感觉到性能上的显着差异。

再次 - 测量!使用.net分析器并测量真正的瓶颈位置,并确定哪些最适合您的特定方案。

你决定使用,请记住,未来的家伙保持你的代码可以知道你住的地方无论非平凡解

+0

感谢您回复我的问题。我只是希望能像你提到的那样解决问题。但我仍然在学习正则表达式工具 ** //如果您的键具有相似的可识别模式(例如:“Key1”,“Key2”等),那么也许您可以在一次使用中进行所有替换编译正则表达式替换工具?// ** – Bendram

+0

像MSDN中的示例一样? https://msdn.microsoft.com/en-us/library/ms149475(v=vs.110).aspx –

+0

是的。类似的东西 – Bendram

1

只是速度和字典性能的一个例子。这是一个4岁的i7-3820

  • 一个线程及时发现在串1“的一些11998948输入” 0毫秒
  • 在时间字符串“一些11998948输入”找到4 0毫秒
  • 找到8在时间1ms
  • 时刻发现在字符串9“一些11998948输入”字符串“一些11998948输入” 1毫秒
  • 在时间1ms
  • 在字符串中发现19发现在字符串“一些11998948输入” 11“的一些11998948输入“时间1ms
  • 在时间1ms
  • 发现在串94“一些11998948输入”在时间发现在字符串“一些11998948输入” 48在时间1ms
  • 发现在串89“一些11998948输入” 1毫秒
  • 实测值98在字符串“一些11998948输入”在时间1ms
  • 时刻发现在串99“一些11998948输入” 1毫秒
  • 在时间1ms
  • 发现在串199“一些11998948输入发现在串119“一些11998948输入” “in time 1ms
  • 及时发现在串894“一些11998948输入” 1毫秒
  • 时刻实测值948在字符串“一些11998948输入” 2ms的
  • 发现在串989“一些11998948输入”在时间2ms
  • 实测值998在串“一些11998948输入”在时间2ms
  • 实测值1199中的字符串中的时间“的一些11998948输入”在时间2ms
  • 实测值1998中的字符串“一些11998948输入” 2ms的
  • 在字符串中发现8948“一些11998948输入”在时间3ms
  • 在字符串“一些11998948输入”在时间3ms
  • 实测值9989中的字符串‘一些11998948输入‘在时间4ms
  • 发现在串19989‘一些11998948输入’在’在时间3ms
  • 发现在串11998’一些11998948输入时间5ms
  • 时刻发现在串98948“一些11998948输入” 21ms
  • 实测值99894中的字符串中的时间“的一些11998948输入”在时间21ms
  • 实测值119989在字符串“一些11998948输入” 25ms的
  • 发现199894在字符串“一些11998948 in把”时间42ms
  • 找到998948字符串‘一些11998948输入’时间214ms
  • 发现在字符串1199894‘’在时间255毫秒
  • 发现在字符串1998948‘一些11998948输入’一些11998948输入时间400毫秒
  • 在时间2127ms

这意味着通过〜1200万层的元件会发现在字符串“一些11998948输入” 11998948需要大约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(); 
+0

这很有趣。我不知道字典更快。感谢您的详细解释。 – Bendram

+0

嗯,dic可能比其他多种类型的集合要慢,但它仍然非常快,你可以在键上使用hashmap特性作为uniqe对象而不是索引号。 –