我正在编写一个程序来计算文本文件中的单词数,该单词已经是小写并用空格分隔.我想使用字典,只计算字典中的单词IF.问题是字典很大(~100万字),每个文本文件也有~5,000字.因此,我在下面写的代码变得非常慢(在quad i7机器上处理一个文档大约需要15秒).我想知道我的编码是否有问题,以及程序的效率是否可以提高.非常感谢你的帮助.代码如下:
public static string WordCount(string countInput)
{
string[] keywords = ReadDic(); /* read dictionary txt file*/
/*then reads the main text file*/
Dictionary<string, int> dict = ReadFile(countInput).Split(' ')
.Select(c => c)
.Where(c => keywords.Contains(c))
.GroupBy(c => c)
.Select(g => new { word = g.Key, count = g.Count() })
.OrderBy(g => g.word)
.ToDictionary(d => d.word, d => d.count);
int s = dict.Sum(e => e.Value);
string k = s.ToString();
return k;
}
Run Code Online (Sandbox Code Playgroud)
您可以通过一次读取一行文本文件而不是构建一个巨大的字符串来大大提高性能.
你可以打电话
File.ReadLines(path).SelectMany(s => s.Split(' '))
Run Code Online (Sandbox Code Playgroud)
不要打电话ReadAllLines; 它需要建立一个庞大的阵列.
你的第一个Select电话是完全没用的.
您的Contains调用将循环遍历文件中每个单词的整个字典.
因此,该Where呼叫是O(n 2)操作.
更改keywords到HashSet<string>.
由于可以在恒定时间内搜索HashSet,因此Where调用将成为O(n)操作,这样做要好得多.
你的第二个Select调用可以与之结合GroupBy,这将削减大量的对象分配:
.GroupBy(c => c, (word, set) => new { word, count = set.Count() })
Run Code Online (Sandbox Code Playgroud)
词典本质上是无序的,所以你的OrderBy电话是无用的浪费时间.