c - 在 C 中有效读取展平文件
问题描述
我正在尝试读取 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);
}
解决方案
(评论:这是我的第二个答案。)我看到 OP 在评论中询问:
您是否碰巧在 C 中有一个示例来读取二进制浮点数?
二进制版本会让任何 ascii 版本都被淘汰。而且更短。
此处 OP 的函数签名已更改为在 return 中包含最大浮点数W
,并返回从文件中实际读取的数字。
size_t read_file(float *W, size_t maxlen)
{
FILE *fp = fopen("C:\\Users\\rohit\\Documents\\GitHub\\base\\numerical\\c\\ReadFile1\\Debug\\data.txt", "r");
return fp ? fread(W, sizeof(float), maxlen, fp) : 0;
}
或者对于更快的东西,你可以使用mmap
... 。但这在 Windows 上不可用。
补充:但是,无缓冲 I/O 可能会更快。以下函数使用单个malloc
和单个无缓冲read
将文件复制到堆中。(注意:尚未对大文件进行测试;可能需要open64
。)
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
void *readFileToHeap(const char *file, int *len) {
void *retval = 0;
ssize_t cnt;
struct stat st;
const int fd = open(file, O_RDONLY, 0);
if (fd < 0)
return printf("Cannot open %s\n", file), (void *)0;
if (fstat(fd, &st))
return perror("fstat()"), close(fd), (void *)0;
if (!(retval = malloc(st.st_size)))
return perror("malloc()"), close(fd), (void *)0;
cnt = read(fd, retval, st.st_size);
close(fd); // not the best: could clobber errno
if (cnt < 0)
return perror("read()"), free(retval), (void *)0;
if (cnt != st.st_size)
return printf("Partial read %d\n", cnt), free(retval), (void *)0;
*len = cnt;
return retval;
}
推荐阅读
- python - 为什么列表上的操作比 numpy 数组上的操作慢
- python - 如何自动选择和处理 /root/facedetect 目录中的每个图像,而不是选择特定图像
- docker - 在浏览器中看不到在 docker 容器内运行的 Hadoop UI
- php - PDOException::(“SQLSTATE [HY000] [2002] 连接被拒绝”在 laravel
- react-native - 保存本地文件反应原生
- raku - 使用模块时如何避免导入默认符号?
- php - 安装后,Owncloud 显示某些软件包的错误
- c++ - 在 C++ 中使用一个为大量计算部分调用 Fortran 程序的算法是否可行?
- node.js - 运行 jest 时多次尝试服务器实例
- mysql - 如何显示非现有值的行