我试图读取一个文件,包含100,000个浮点数,如 0.12345678 或 -0.1234567 ,用c ++中的空格分隔。我用 fscanf()来读取文件,代码是这样的:
FILE *fid = fopen("testingfile.txt", "r");
if (fid == NULL)
return false;
float v;
for (int i = 0; i < 100000000; i++)
fscanf(fid, "%f", &v);
fclose(fid);
该文件的大小为1199999988字节,并使用 fscanf()完成 18秒 以完成阅读。因此,我想使用 mmap()来加快阅读速度,代码如下:
#define FILEPATH "testingfile.txt"
char text[10] = {'\0'};
struct stat s;
int status = stat(FILEPATH, &s);
int fd = open(FILEPATH, O_RDONLY);
if (fd == -1)
{
perror("Error opening file for reading");
return 0;
}
char *map = (char *)mmap(NULL, s.st_size, PROT_READ, MAP_SHARED, fd, 0);
close(fd);
if (map == MAP_FAILED)
{
perror("Error mmapping the file");
return 0;
}
for (int i = 0,j=0; i < s.st_size; i++)
{
if (isspace(map[i]))
{
text[j] = '\0';
j = 0;
float v = atof(text);
for (int j = 0; j < 10; j++)
text[j] = '\0';
continue;
}
text[j] = map[i];
j++;
}
if (munmap(map, s.st_size) == -1)
{
return 0;
}
但是,仍然需要 14.5秒 才能完成阅读。我发现最耗时的部分是将数组转换为浮点数,其消耗大约 10秒
所以我有三个问题:
有什么方法可以直接读取float而不是char或
有没有更好的方法将char数组转换为float
fscanf
如何识别浮点值并读取它,这比atof()
快得多。
提前致谢!
答案 0 :(得分:0)
根据给出的建议,以下是此问题的两种可能解决方案:
第一种方法有点“愚蠢”。由于存储浮点数值的格式是已知的,因此可以在不使用atof()
的情况下轻松完成从char数组到float数的转换。
删除atof()
后,只需 8秒 即可完成同一文件的阅读和转换。
第二种方法是更改文件中浮点数的存储格式(由Jeremy Friesner建议)。浮点数值以二进制格式存储,因此不需要mmap()
的转换部分。代码变成这样:
#define FILEPATH "myfile.bin"
int main()
{
int start_s = clock();
struct stat s;
int status = stat(FILEPATH, &s);
int fd = open(FILEPATH, O_RDONLY);
if (fd == -1)
{
perror("Error opening file for reading");
return 0;
}
float *map = (float *)mmap(NULL, s.st_size, PROT_READ, MAP_SHARED, fd, 0);
close(fd);
if (map == MAP_FAILED)
{
perror("Error mmapping the file");
return 0;
}
for (int i = 0; i < s.st_size / 4; i++)
{
float v = map[i];
}
if (munmap(map, s.st_size) == -1)
{
return 0;
}
}
这将大大减少以相同大小读取文件所需的时间。