这个问题之后,一个疑问出现了:
一旦fopen()比open()快(至少对于顺序写入/就绪操作),前者是一个库,后者是一个系统调用,那么fopen()在POSIX编译操作系统中做什么系统调用?
调用open
fopen
本身并不比open
快;不可能,这是open
加上一些额外的功。链接问题中描述的性能优势来自于"缓冲"。由FILE
对象在其整个生命周期内完成。实际的优化是调用write
原语更少的次数,每次提供更多的数据。下面是一个简单的方法来演示效果:编译这个程序。
#define _XOPEN_SOURCE 700
#include <stdlib.h>
#include <stdio.h>
int main(int argc, char **argv)
{
if (argc != 3) return 1;
long count = atol(argv[1]);
long chunk = atol(argv[2]);
if (count < 1 || chunk < 0) return 1;
FILE *sink = fopen("/dev/null", "wb");
if (!sink) return 1;
if (chunk) {
char *buf = malloc(chunk);
if (!buf) return 1;
if (setvbuf(sink, buf, _IOFBF, chunk)) return 1;
} else {
if (setvbuf(sink, 0, _IONBF, 0)) return 1;
}
while (count--) putc_unlocked('.', sink);
return 0;
}
它接受两个参数:按顺序写的总字节数和输出缓冲区的大小。用不同的参数值运行它并计时它的性能;你应该看到,例如
./a.out $((1024*1024*128)) 1
比
慢得多./a.out $((1024*1024*128)) 8192
第一个数字需要非常大才能测量差异。运行了一段时间后,运行
strace ./a.out 50 1
和
strace ./a.out 50 50
来理解在系统调用级别上发生的事情的区别。(如果您使用的是Linux以外的操作系统,请将strace
替换为该操作系统的等效命令。)