2016-05-12 107 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對象而不是索引號。 –