2009-10-11 45 views
17

我正在写一个需要读取相当大的文件的应用程序。我一直想知道现代Windows XP计算机上读取缓冲区的最佳大小。我搜索了一下,发现了很多例子,其中最佳尺寸为1024。最佳文件缓冲区读取大小?

这里是我的意思的一个片段:

long pointer = 0; 
buffer = new byte[1024]; // What's a good size here ? 
while (pointer < input.Length) 
{ 
    pointer += input.Read(buffer, 0, buffer.Length); 
} 

我的应用程序是相当简单的,所以我不打算写任何基准测试代码,但想知道什么大小适用?

+0

可能会有所帮助:http://stackoverflow.com/questions/19558435/what-is-the-best-buffer-size-when-using-binaryreader-to-read-big-files-1gb/19837238? noredirect = 1#19837238 – 2013-11-07 13:34:09

回答

7

1k缓冲区大小似乎有点小。一般来说,没有“一刀切”的缓冲区大小。您需要设置适合您算法行为的缓冲区大小。现在,一般来说,拥有一个非常巨大的缓冲区并不是一个好主意,但是,如果它太小或者不符合你处理每个块的方式也不是那么好。

如果您在处理数据之前只是简单地将数据块逐个读入内存,我会使用更大的缓冲区。我可能会使用8k或16k,但可能不会更大。另一方面,如果以流方式处理数据,读取块并在读取下一个较小的缓冲区之前进行处理可能会更有用。更好的是,如果您正在流式传输具有结构的数据,那么我会更改读取的数据量以与您正在阅读的数据类型特别匹配。例如,如果您正在读取包含4个字符的代码,一个浮点数和一个字符串的二进制数据,我会将4个字符的代码读取为4个字节的数组以及浮点数。我会读取字符串的长度,然后创建一个缓冲区来一次读取整个字符串数据块。

如果你正在做流数据处理,我会看看BinaryReader和BinaryWriter类。这些允许您非常容易地处理二进制数据,而不必担心数据本身。它还允许您将缓冲区大小与正在使用的实际数据分离。您可以在底层流上设置一个16k缓冲区,并轻松地使用BinaryReader读取各个数据值。

+0

感谢您使用BinaryReader的建议。使用BinaryReader有助于读取字符串,因为我不需要编写管道代码来编写长度。 我将测试8K和16K读取以查看性能是否提高。就个人而言,我不在乎尺寸是多少,但一些质量保证人员想要了解我们是否可以通过更好地利用硬件和操作系统来提高性能。 – 2009-10-12 00:52:41

+0

如果您只是将大量数据传输到内存中,您可以尝试更大的缓冲区。只要您将缓冲区大小保持为磁盘簇大小的倍数,您应该是最佳的。说实话,我认为我90年代末和2000年初的做法仍然有很深的根深蒂固。如果您正在运行此程序的系统具有现代性和高性能,则32k,64k甚至更大的缓冲区可能会有所帮助。如果你太大(例如1mb),随着其他因素的增加(即交换颠簸),你可能会看到收益递减。关键是将读取与低级行为进行匹配。 – jrista 2009-10-12 05:02:32

3

取决于您在访问时间和内存使用情况之间划定界限的位置。缓冲区越大,速度越快 - 但在内存方面更昂贵。 读取倍数的文件系统簇大小可能是最高效的,在使用NTFS的Windows XP系统中,4K是默认簇大小。

你可以看到这个链接Default cluster size for NTFS, FAT, and exFAT

再见。

+0

我会尝试@jrista建议的8K和16K读取。有趣的是,这篇文章说windows使用8k群集的16 TB磁盘分区。我还没有看到过之前很大的一个分区。 – 2009-10-12 00:56:45

+1

Andrew,8K和16K是4K的多个硬件 – RRUZ 2009-10-12 01:21:03

+0

较旧的硬盘驱动器一次读取和写入整个512字节的扇区。现代硬盘驱动器一次可读写整个4096字节的扇区。 Windows NTFS有一个4096字节的(默认)群集大小。使用Windows的事件跟踪功能,你可以看到Windows最常见的是16,384字节的实际硬盘驱动器I/O以及4,096个字节(以及较少的8192和49152字节)。理想情况下保持4k或16384字节的倍数。 – 2013-10-12 19:55:02