网上看了很多文章, 都说 fread 比 read 读取数据更快云云, 今天在我的 Mac 上做了一个小测试, 结果比较意外
- #include <stdio.h>
- #include <unistd.h>
- #include <time.h>
- #include <fcntl.h>
- void test_fread(char *buff, int num);
- void test_read(char *buff, int num);
- int main() {
- char buff[100];
- test_fread(buff, sizeof(buff));
- test_read(buff, sizeof(buff));
- }
- void test_fread(char *buff, int num) {
- clock_t start, finish;
- double duration;
- start = clock();
- FILE *fp;
- char filename[] = "a.txt";
- fp = fopen(filename, "r");
- int i=0;
- while(1) {
- i++;
- fread(buff, num, 1, fp);
- if(feof(fp)) {
- break;
- }
- }
- fclose(fp);
- finish = clock();
- duration = (double)(finish - start) / CLOCKS_PER_SEC;
- printf( "%f seconds\n", duration );
- }
- void test_read(char *buff, int num) {
- clock_t start, finish;
- double duration;
- start = clock();
- int fp;
- char filename[] = "a.txt";
- fp = open(filename, O_RDONLY);
- int i = 0;
- while(read(fp, buff, num)>0){
- i++;
- };
- close(fp);
- finish = clock();
- duration = (double)(finish - start) / CLOCKS_PER_SEC;
- printf( "%f seconds\n", duration );
- }
- View Code
经不断调整 第 10 行 buff 的大小, 测得结果如下:
buff 大小 Byte | fread 执行时间 | fread 系统调用次数 | read 执行时间 | read 系统调用次数 |
8192 | 0.001721 | 775 | 0.001416 | 775 |
4096 | 0.002482 | 1548 | 0.001804 | 1548 |
2048 | 002431 | 1548 | 003210 | 3094 |
1024 | 003065 | 1548 | 005447 | 3836 |
fread 是自带缓冲区 (在我的 Mac 上测试结果为 4096B)
当 sizeof(buff)>= 4096 时, 系统使用 sizeof(buff) 作为缓冲区大小. 系统调用的次数 = 待读取字节数 / sizeof(buff)
当 sizeof(buff) < 4096 时, 系统使用 sizeof(buff) 作为缓冲区大小. 系统调用的次数 = 待读取字节数 / 4096
而 read 的计算公式就比较简单了~ 系统调用的次数 = 待读取字节数 / sizeof(buff)
PS: 测试环境为 Mac, 系统调用次数可以通过命令查看 sudo dtruss -a ./a
总结:
当 buff 设置的比较小时, fread 方法由于具有更大的缓冲区, 系统调用次数变少, 效率相比于 read 更快.
当 buff 设置的比较大时, fread 方法与 read 方法具有了相同大小的缓冲区, 系统调用次数相同. 但由于 fread 是在 read 基础上的封装, 做了更多的操作, 效率相比于 read 更慢.
效率相同时的 buff 值, 应该小于 4096B 一些.
系统调用的次数才是性能的瓶颈~~~!!!
来源: http://www.bubuko.com/infodetail-3217069.html