有效地求和大文件中的所有字节值

时间:2019-04-11 05:53:17

标签: c# arrays numbers byte task-parallel-library

我需要从5 + GB文件中找到所有字节值的总和。问题是关于性能的:当我只使用诸如.Sum().Aggregate()foreach之类的常用表达式并将所有这些都放在Parallel.For循环中时,它确实起作用,但是我被告知有一些程序快10倍。这是我的。 (此外,我正在使用FileStream实例并启用了异步模式,并且MemoryMappedFile可以通读)

// ... Above there is some Parallel.For loop
// ... Which is about to read file in chunks
// Prepare array to read bytes 
Byte[] chunk = new Byte[readingChunkSize];
// Create an accessor to perform it
using (var viewAccessor = memMappedFile.CreateViewAccessor(overallMemoryOffset, readingChunkSize, MemoryMappedFileAccess.Read))
{
    // Loading desired data
    viewAccessor.ReadArray(
        0,
        chunk,
        0,
        Convert.ToInt32(readingChunkSize));
}
// Summing all the byte values 
Int64 sumFragment = 0;
for (Int64 i = 0; i < readingChunkSize; i++)
{
    sumFragment += chunk[i];
}
// Adding it to result
Interlocked.Add(ref bytesSum, sumFragment);

我想这不太明显,因为添加更多的Task这样的异步操作只会降低性能。

1 个答案:

答案 0 :(得分:0)

您可以尝试将字节的总和卸载到使用者线程上,但是最终获得总和的速度受到可以从文件系统读取字节的速度的限制。就我个人而言,我已经通过使用在多个线程中运行的多个读取器来读取单个大文件进行了实验,并且仅在从我的SSD读取时,我看到的改进不超过x2。实际上,从我的外部磁盘上读取单个读取器会更快。我没有用过MemoryMappedFile,只有stream.Read