此方法从字符串数组中获取最常用的单词。 对于大型阵列,它的工作速度非常慢(对于70.000个字符串,则为190.000毫秒)。 我已经测量过(使用 秒表() ),它的第一部分是最慢的部分:
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;
}
如何提高此方法的性能?
答案 0 :(得分:5)
在列表中使用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
一次来加快速度:
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