在 C++ 中读取文件包含带有 mmap() 的浮点数

Reading file consists of float number with mmap() in C++

我正在尝试读取一个由 100000000 个浮点数组成的文件,例如 0.12345678-0.1234567,由 space 分隔在 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 字节,用 18 秒 完成读取 fscanf()。因此,我想使用mmap()来加快读取速度,代码是这样的:

#define FILEPATH "testingfile.txt"

char text[10] = {'[=11=]'};
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] = '[=11=]';
        j = 0;
        float v = atof(text);
        for (int j = 0; j < 10; j++)
            text[j] = '[=11=]';
        continue;
    }
    text[j] = map[i];
    j++;

}
if (munmap(map, s.st_size) == -1)
{
    return 0;
}

但是,完成阅读仍然需要大约 14.5 秒。我发现最耗时的部分是将数组转换为浮点数,耗时约 10 秒

所以我有三个问题:

  1. 有什么方法可以直接读取 float 而不是 char 或

  2. 有没有更好的方法将char数组转为float

  3. fscanf如何识别浮点值并读取,比atof().

  4. 快多了

提前致谢!

根据给出的建议,这里有两个可能的解决方案:

第一种方法有点"stupid"。由于存储的浮点数值的格式是已知的,因此无需使用 atof() 即可轻松完成从字符数组到浮点数的转换。 通过删除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;
}
}

这将大大减少读取相同大小的文件所需的时间。