9

可能重复:
使用 FileInputStream 时如何确定理想的缓冲区大小?

fread($file, 8192)比 更好或更安全的fread($file, 10000)吗?为什么大多数示例使用 2 的幂?

4

3 回答 3

7

请参阅这个问题公认答案How do you determine the Ideal buffer size when using FileInputStream? .

大多数文件系统配置为使用 4096 或 8192 的块大小。理论上,如果您配置缓冲区大小以便读取比磁盘块多几个字节,则对文件系统的操作可能非常低效(即,如果您将缓冲区配置为一次读取 4100 个字节,每次读取需要文件系统读取 2 次块)。如果这些块已经在缓存中,那么您最终会付出 RAM -> L3/L2 缓存延迟的代价。如果你不走运并且块还没有在缓存中,那么你也要付出磁盘-> RAM 延迟的代价。

这就是为什么您会看到大多数缓冲区大小为 2 的幂,并且通常大于(或等于)磁盘块大小。这意味着您的一个流读取可能会导致多个磁盘块读取 - 但这些读取将始终使用完整块 - 不会浪费读取。

尽管这个问题与 Java 相关,但答案却不是。此外,它几乎与语言无关。该答案涵盖了我所知道的有关缓冲区大小的所有因素。

于 2012-12-04T17:12:33.783 回答
2

要么是因为:

  • 选择任意数字的程序员喜欢选择两个权力,或
  • 在某种过早的优化中,程序员认为读取块大小的倍数会带来某种速度提升。
于 2012-12-04T16:53:10.170 回答
2

操作系统以为单位分配内存(通常为 4k - 但有时为 8k)。

在这种情况下,使用 8192 字节的倍数的缓冲区大小可以提高内存分配的效率(因为它也适合 4096 字节的倍数)。

如果您请求 13k 的内存,无论如何都会使用 16k,所以为什么不从 16k 开始。

CPU 指令集也经过优化,可以处理与某些边界对齐的数据,无论是 32、64 还是 128 位。使用与 3 位或 5 位或其他奇怪的数据对齐的数据会增加额外的处理开销。

这不是特定于 PHP 的,它在操作系统自己的内存管理之上使用 Zend 内存管理器,并且可能会预先分配更大的内存块,并将内存管理的问题从用户身上转移开。

于 2012-12-04T17:21:05.607 回答