[英]Speed up working with big arrays of string in c#
此方法從字符串數組中獲取最常用的單詞。 對於大型數組,它的工作速度非常慢(例如,對於70.000個字符串,則為190.000毫秒)。 我已經測量(使用Stopwatch() ),它的第一部分是最慢的部分:
public static List<WordDouble> MostFrequentWords(double count, string[] words)
{
var wordsAndNumbers = new List<WordDouble>();
foreach (var word in words)
{
if (wordsAndNumbers.Exists(e => e.Word == word.ToLower()))
wordsAndNumbers[wordsAndNumbers.FindIndex(e => e.Word == word.ToLower())].Count++;
else
{
var addWord = new WordDouble();
addWord.Word = word.ToLower();
addWord.Count = 1;
wordsAndNumbers.Add(addWord);
}
}
/*method goes on, other parts work fast and do not need improvement */
...
return something;
}
public class WordDouble
{
public string Word;
public double Count;
}
如何改善這種方法的性能?
使用列表中的Exists
檢查項目是O(n)操作,而字典中的檢查項目是O(1)操作。
這只需要一小部分時間(實際上是大約1/2200的時間):
Dictionary<string, int> wordsAndNumbers = new Dictionary<string, int>();
foreach (string word in words) {
if (wordsAndNumbers.ContainsKey(word.ToLower())) {
wordsAndNumbers[word.ToLower()]++;
} else {
wordsAndNumbers.Add(word.ToLower(), 1);
}
}
這是使用70000個字符串分別針對原始代碼,我的代碼和控制台的代碼進行的測試運行的結果:
00:01:21.0804944
00:00:00.0360415
00:00:00.1060375
您甚至可以通過在ToLower
僅執行一次ToLower
來加快速度:
var wordsAndNumbers = new Dictionary<string, int>();
foreach (var word in words) {
string s = word.ToLower();
if (wordsAndNumbers.ContainsKey(s)) {
wordsAndNumbers[s]++;
} else {
wordsAndNumbers.Add(s, 1);
}
}
測試運行:
00:00:00.0235761
首先,為什么要使用雙字數字? 使用較長的Dictionary,切勿為了比較而強制降低。
Dictionary<string,long> wordsAndNumbers = new
Dictionary<string,long>(StringComparer.OrdinalIgnoreCase);
foreach(var word in words)
{
if (!wordsAndNumbers.ContainsKey(word))
wordsAndNumbers[word] = 1;
else
wordsAndNumbers[word]++;
}
使用70000個單詞時,我得到以下運行時:00:00:00.0152345,這比要花00:00:00.0320127在我的計算機上降低解決方案的速度要快得多
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.