我正在尝试读取一个大文件,它在C中每行有一个浮点数。为此,我将下面的代码组合在一起。当在小数据上测试时,它工作得很好。然而,当以这种方式读取6亿个数字时,速度非常慢。有什么建议可以让我加快速度吗?我通过python生成原始文件,因此也可以重新格式化数据(例如,在一行中用逗号分隔多个数字)。任何对此方法如此缓慢的原因的洞察都将不胜感激。
void read_file(float *W)
{
FILE *fp;
int i = 0;
// In this file, one row should contain only one NUMBER!!
// So flatten the matrix.
if (fp = fopen("C:\\Users\\rohit\\Documents\\GitHub\\base\\numerical\\c\\ReadFile1\\Debug\\data.txt", "r")) {
while (fscanf(fp, "%f", &W[i]) != EOF) {
++i;
}
fclose(fp);
}
fclose(fp);
scanf("%d",&i);
}
发布于 2018-08-03 02:51:08
几年前我也遇到过类似的问题。解决方案是用fgets
和strtod
替换fscanf
。如果我没记错的话,这带来了超过10倍的改进。
所以你的循环:
while (fscanf(fp, "%f", &W[i]) != EOF) {
++i;
}
应该看起来像这样:
while (fgets(buf, sizeof buf, fp)) {
W[i++] = strtod(buf, 0);
}
编辑:错误检查总是一个好主意。因此,加上这一点,简单的两行代码增长到大约十行:
char buf[80];
errno = 0;
while (!errno && fgets(buf, sizeof buf, fp)) {
W[i++] = strtod(buf, 0);
}
if (errno) { // Maybe ERANGE or EINVAL from strtod, or a read error like EINTR
int save = errno;
printf("errno=%d reading line %d\n", save, i); // or perror()
exit(1);
}
编辑2:关于错误检查,输入文件可能很容易包含诸如nan
或inf
之类的文本,可能来自上游的某个bug。但是strtod
和fscanf
非常乐意解析这些内容。这可能会在您的代码中导致神秘的问题。
但它很容易检查。添加代码:
int bad = 0;
for (int j = 0; j < i; j++)
bad += !isnormal(W[j]); // check for nan, inf, etc.
if (bad) {
// ... handle error
}
将其放在一个单独的、简单的循环中可以使编译器更容易优化(理论上),特别是当您使用#pragma GCC optimize ("unroll-loops")
之类的东西时。
https://stackoverflow.com/questions/51660090
复制相似问题