如何提高从文件中读取数据的速度?

3
我正在读取一个包含大约170万行的文本文件,每行都由3个整数组成。我面临的问题是,循环遍历并将整数存储到向量中需要约30秒的时间。
以下是我写的代码:
std::ifstream finVertices("Phantom Data/FA_vertices.txt", std::ios::in);
    if (!finVertices)
    {
        std::cerr << "Can not open verticies.txt" << std::endl;
    }

    std::cout << "Loading verticies" << std::endl;

    std::string verticesLineBuffer;
    while (std::getline(finVertices, verticesLineBuffer))
    {
        std::istringstream voxelStringCoordinates(verticesLineBuffer);
        GLfloat x, y, z;
        voxelStringCoordinates >> x >> y >> z;
        vertices.push_back(glm::vec3(y, z, x));
    }

    finVertices.close();

文本文件内容示例:

297 13 164
297 13 165
297 14 164
297 14 165
298 13 164
298 13 165

问题:如何从txt文件中提高读取的效率?

编辑:感谢您的帮助,通过您的帮助我解决了这个问题。以下是代码:

std::ifstream is(fileName, std::ifstream::binary);

    if (is) {
        is.seekg(0, is.end);
        int length = is.tellg();
        is.seekg(0, is.beg);

        char* buffer = new char[length];

        is.read(buffer, length);

        is.close();

        for (unsigned int i = 0; i < is.gcount(); i++)
        {
            // here can get access to each indiviual character
        }

2
"push_back" 可能是你的问题所在。如果你知道你需要多少个顶点,可以在创建向量时进行预留。 - drescherjm
2
vertices 是否有足够的预留空间,以免需要重新分配内存? - Eljay
2
“iostreams” 是效率低下的模型。当速度很重要时,您不想使用 “iostreams” 或 “std::string”。我会使用 mmap 将整个文件映射到内存中,然后迭代它,使用 std::from_chars 逐个提取整数值。 - Sam Varshavchik
2
为什么要使用字符串流而不是直接从文件中读取? - Mark Ransom
1
@Elnur 看看能否将文件大小用作一些启发式方法,以指示文件中存在的元素的合理上限。如果您可以控制文件格式,则最好使文件的第一行成为元信息,例如它包含多少行。然后,您将知道要保留多大的向量。 - JohnFilleau
显示剩余7条评论
1个回答

4

1) 一次读取更大的块,例如1MiB或10MiB或一次性读取整个文件。然后从读取文件(或块)时的内存中处理数据。或使用mmap映射文件。

2) 在向vertices向量添加元素之前调用reserve()函数以减少必须进行的分配数量。

3) 使用启用了优化的编译选项编译您的代码(即发行版编译)。


https://en.cppreference.com/w/cpp/io/basic_streambuf/pubsetbuf 有一个增加 ifstream 缓冲区大小的示例。 - Botje

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接