原创: hxj7
本文粗浅比较了C语言中常用的几种读取文件的函数的效率,并给出了几段求取某列平均值的代码。
第一部分:比较读取文件的效率
在之前的文章《生信(五)awk求取某一列的平均值》中,笔者曾经给出过C语言求取某列平均值的代码,但是最近回顾时发现,这段代码至少有几点不足:
1. 利用 fgetc 函数来读取文件,现在看来效率不高。
2. 如果文件最后没有一个空白行的话,会陷入无限循环。也就是对 EOF 的处理不完善。
大家都知道,C语言读取文件的常用函数有 fgetc、fgets、fread 以及 fscanf 等。笔者曾经一度以为就读取文件的效率而言,fgetc 不亚于其他函数。但是究竟是不是这样,还是自己验证一下让自己信服。
首先随机生成一个文件,1000万行,4列(该文件下面还会用到)。我们看一下上述函数读取文件的效率:
从上图中可以看出,fread 的效率最高,fgetc 的效率最低。当然这种比较很粗浅,但是能大概看出趋势。
各个函数读取文件的代码如下:其中 main 函数是一样的,只是 readFile 函数的实现不同。
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define BUFSIZE 4096
void readFile(FILE* fp);
int main(int argc, char* argv[]) {
FILE *fp;
time_t start, end;
start = time(NULL);
if (argc < 2) {
printf("Usage: %s <filename>\n", argv[0]);
return 1;
}
if ((fp = fopen(argv[1], "r")) == NULL) {
printf("Error: cannot open file\n");
return 1;
}
readFile(fp);
fclose(fp);
end = time(NULL);
printf("time spent: %d seconds\n", end - start);
return 0;
}
// readFile_fgetc:
void readFile(FILE* fp) {
char c;
while ((c = fgetc(fp)) != EOF)
;
}
// readFile_fgets:
void readFile(FILE* fp) {
char buf[BUFSIZE];
while (fgets(buf, MAXLINE, fp) != NULL)
;
}
// readFile_fread:
void readFile(FILE* fp) {
char buf[BUFSIZE];
while (fread