时间()系统调用的开销 - 相对于文件操作

时间:2010-07-01 00:03:47

标签: c performance unix system

调用times()与读取行fread()等文件操作的相对开销是多少。

我意识到这可能与操作系统有所不同,取决于该行的长度,文件所在的位置,是否真的是被阻止的管道(不是)等等。

该文件很可能不是本地文件,而是位于本地网络某处的已安装NFS驱动器上。常见的情况是一行长度为20个字符。如果有帮助,请假设Linux内核2.6.9。代码将在Windows上运行。

我只是在寻找一个粗略的指南。它是否处于同一数量级?快点?慢?

终极目标:我正在考虑实现进度回调例程,但不想太频繁地调用(因为回调可能非常昂贵)。大部分工作是读取文本文件(逐行)并对该行执行某些操作。不幸的是,有些行非常很长,所以简单地调用每个N行在常见的病态病例中无效。

我正在避免写一个基准,因为我害怕写错了,我希望人群的智慧比我半生不熟的测试更大。

3 个答案:

答案 0 :(得分:3)

fread()是C库函数,而不是系统调用。默认情况下,fread()fwrite()fgets()和朋友都是缓冲I / O(请参阅setbuf),这意味着该库会分配一个缓冲区,该缓冲区会降低{需要进行{1}}和read()次系统调用。

这意味着如果您从文件中按顺序读取,则库将仅发出一次系统调用,例如100次读取(取决于缓冲区大小以及您一次读取的数据量)。

然而,当进行write()read()系统调用时,它们肯定会比调用write()慢,这仅仅是因为需要在您之间交换的数据量很大程序和内核。如果数据缓存在OS的缓冲区中(例如,它刚刚在同一台机器上由另一个进程写入),那么它仍然会非常快。如果没有缓存数据,那么您将不得不等待I / O(无论是磁盘还是网络),这相当慢。

如果数据在NFS上变得新鲜,那么我非常有信心平均调用times()会比times()更快。

答案 1 :(得分:2)

在Linux上,您可以编写一个小程序,对times()和fread()进行大量调用,并使用strace -c

测量系统调用次数

e.g

for (i = 0; i < RUNS; i++) {
        times(&t_buf);
        fread(buf,1,BUF,fh);
}

这是BUF 4096(fread每次实际调用read())

# strace -c ./time_times
% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ----------------
 59.77    0.001988           0    100000           read
 40.23    0.001338           0     99999           times

这就是BUF 16

% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ----------------
 99.00    0.001387           0     99999           times
  1.00    0.000014           0       392           read

答案 2 :(得分:1)

times()只读取内核维护的特定于流程的数据。内核维护数据,以便在进程退出时为wait()系统调用提供信息。因此,无论是否调用times(),都始终保持数据。调用times()的额外开销非常低

fread(),fwrite()等调用底层系统调用 - read()&amp; write(),它调用驱动程序。然后驱动程序将数据放在内核缓冲区中。就资源而言,这比调用times()要昂贵得多。

这是你要问的吗?