C:输出例程在缓冲方面的效率如何



我找不到任何关于在使用fprintffwrite写入文件时是否已经隐式完成缓冲的信息。我知道这可能是实现/平台相关的功能。我感兴趣的是,我是否可以期望它至少在Windows,Linux或Mac OS X等现代流行平台上有效实现?

AFAIK,通常 I/O 例程的缓冲在 2 个级别上完成:

  1. 级别:可以是C标准库,也可以是Java SDK(BufferedOutputStream)等;
  2. 操作系统级别:现代平台广泛缓存/缓冲 I/O 操作。

我的问题是关于#1,而不是#2(因为我知道这已经是真的)。换句话说,我是否可以期望所有现代平台的 C 标准库实现都利用缓冲?

如果没有,那么手动创建一个缓冲区(具有巧妙选择的大小)并在溢出时刷新它是解决问题的好方法吗?

结论


感谢所有指出setbufsetvbuf等功能的人。这些是我一直在寻找的确切证据来回答我的问题。有用的摘录:

所有文件都使用默认分配的缓冲区(完全缓冲)打开 如果已知它们不是指交互式设备。此函数 可用于设置要用作缓冲区的特定内存块 或禁用流的缓冲。

默认情况下,默认

stdinstdout完全缓冲,如果 众所周知,它们不是指交互式设备。否则,他们 默认情况下可以是缓冲的,也可以是无缓冲的,具体取决于 系统和库实现。stderr也是如此,它 默认情况下始终为行缓冲或未缓冲。

在大多数情况下,

stdio 例程的缓冲会进行调整,以与相关操作系统的典型块大小保持一致。这样做是为了在默认情况下优化 I/O 操作的数量。当然,您可以随时使用setbuf()/setvbuf()例程来更改它。

除非您正在做一些特殊的事情,否则您应该坚持使用默认缓冲,因为您可以非常确定它在您的操作系统上是最佳的(对于典型场景)。

唯一证明这一点的情况是,当您想使用 stdio 库与不适合它的 I/O 通道进行交互时,在这种情况下,您可能希望完全禁用缓冲。但我不会经常看到这种情况。

您可以放心地假设标准 I/O 在任何现代系统上都得到了合理的缓冲。

正如@David所说,您可以期待合理的缓冲(在两个级别)。

然而,fprintffwrite之间可能存在巨大的差异,因为fprintf解释格式字符串。如果你堆叠采样,你会发现很大一部分时间将双精度转换为字符串,以及类似的东西。

C IO 库允许使用 setvbuf 控制缓冲完成的方式(在应用程序内部,在操作系统执行的操作之前)。 如果您没有指定任何内容,则标准要求"打开时,流被完全缓冲当且仅当可以确定它不是",该要求也适用于stdinstdout,而即使可以检测到它被定向到非交互式设备,stderr也不会缓冲。

最新更新