虽然最被赞同的回答是正确的,但它缺乏使用多核处理的内容。在我的情况下,我使用 PLink,因为我有12个核心:
Parallel.ForEach(
File.ReadLines(filename), //returns IEumberable<string>: lazy-loading
new ParallelOptions { MaxDegreeOfParallelism = Environment.ProcessorCount },
(line, state, index) =>
{
//process line value
}
);
值得一提的是,我曾在面试中被问到如何返回出现次数最多的前十个元素。
var result = new ConcurrentDictionary<string, int>(StringComparer.InvariantCultureIgnoreCase);
Parallel.ForEach(
File.ReadLines(filename),
new ParallelOptions { MaxDegreeOfParallelism = Environment.ProcessorCount },
(line, state, index) =>
{
result.AddOrUpdate(line, 1, (key, val) => val + 1);
}
);
return result
.OrderByDescending(x => x.Value)
.Take(10)
.Select(x => x.Value);
Benchmarking:
BenchmarkDotNet=v0.12.1, 操作系统=Windows 10.0.19042
Intel Core i7-8700K CPU 3.70GHz (Coffee Lake), 1个CPU,12逻辑和6物理核心
[主机]:.NET Framework 4.8 (4.8.4250.0),X64 RyuJIT
DefaultJob:.NET Framework 4.8 (4.8.4250.0),X64 RyuJIT
方法 |
平均值 |
误差 |
标准差 |
Gen 0 |
Gen 1 |
Gen 2 |
已分配内存 |
GetTopWordsSync |
33.03秒 |
0.175秒 |
0.155秒 |
1194000 |
314000 |
7000 |
7.06 GB |
GetTopWordsParallel |
10.89秒 |
0.121秒 |
0.113秒 |
1225000 |
354000 |
8000 |
7.18 GB |
正如您所看到的,性能提高了75%。
但请注意,这7GB立即加载到内存中,由于它是一个blob,因此对GC施加了太大的压力。
foreach (string line in File.ReadLines(path).Skip(skip))
。那太糟糕了。 - mafu