调用times()
与读取行fread()
等文件操作的相对开销是多少。
我意识到这可能与操作系统有所不同,取决于该行的长度,文件所在的位置,是否真的是被阻止的管道(不是)等等。
该文件很可能不是本地文件,而是位于本地网络某处的已安装NFS驱动器上。常见的情况是一行长度为20个字符。如果有帮助,请假设Linux内核2.6.9。代码将不在Windows上运行。
我只是在寻找一个粗略的指南。它是否处于同一数量级?快点?慢?
终极目标:我正在考虑实现进度回调例程,但不想太频繁地调用(因为回调可能非常昂贵)。大部分工作是读取文本文件(逐行)并对该行执行某些操作。不幸的是,有些行非常很长,所以简单地调用每个N
行在常见的病态病例中无效。
我正在避免写一个基准,因为我害怕写错了,我希望人群的智慧比我半生不熟的测试更大。
答案 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()要昂贵得多。
这是你要问的吗?