AI/O效率测试来自APUE:
测试文件据称为“98.5 MB,300 万行”。
“图3.6”中使用的代码:
#include "apue.h"
#define BUFFSIZE 4096
int
main(void)
{
int n;
char buf[BUFFSIZE];
while ((n = read(STDIN_FILENO, buf, BUFFSIZE)) > 0)
if (write(STDOUT_FILENO, buf, n) != n)
err_sys("write error");
if (n < 0)
err_sys("read error");
exit(0);
}
最佳时间见图3.6:使用不同BUFFSIZE
并选择最佳时间
图 3.6 的单字节时间: 使用BUFFSIZE=1
err_sys
只是一个用于错误处理的包装函数。
apue.h
也是一个包装头文件。
代码使用fgets
:
#include "apue.h"
int
main(void)
{
int c;
while ((c = fgetc(stdin)) != EOF){
if (fputc(c, stdout) == EOF)
err_sys("output error");
}
if (ferror(stdin))
err_sys("input error");
exit(0);
}
问题来自:
这些计时数字的最后一个有趣点是该版本比图 3.6 中的版本
fgetc
快得多。BUFFSIZE=1
两者涉及相同数量的函数调用(大约 2 亿次),但该fgetc
版本在用户 CPU 时间方面快了 16 倍以上,在时钟时间方面快了近 39 倍。不同之处在于,使用 read 的版本执行了 2 亿个函数调用,而函数调用又执行了 2 亿个系统调用。在该fgetc
版本中,我们仍然执行 2 亿次函数调用,但这意味着仅25,224系统调用。系统调用通常比普通函数调用昂贵得多。
测试文件98.5 MB ≈ 100 M,所以每个 I/O 函数调用1亿次==2亿次调用,这里没有问题。
但2亿如何fgets
转化为25,224系统调用?
在该
fgetc
版本中,我们仍然执行 2 亿次函数调用,但这意味着仅25,224系统调用。
怎么25,224计算过?