fgets 的 2 亿次函数调用如何转化为 25,224 次系统调用?

fgets 的 2 亿次函数调用如何转化为 25,224 次系统调用?

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计算过?

相关内容