c++编写和读取文本文件是非常缓慢的,任何替代方案

c++ writing and reading text file is very slow, any alternatives?

本文关键字:缓慢 任何替 方案 非常 读取 文件 取文本 c++      更新时间:2023-10-16

我目前正在为一款游戏编写代码,我有点卡在保存和加载关卡上。我使用这段代码:

    bool WorldGen::GenerateNewWorld(unsigned int seed, int width)
{
    std::cout << "World generating..." << std::endl;
    int heigth = 1; //2D perlin noise instead of 3D
    m_WorldSizeX = width;
    m_WorldSizeY = 1800; //add a int height if implementing different world sizes
    // Create a PerlinNoise object with a random permutation vector generated with seed
    PerlinNoise(seed);
    std::vector<byte> arrMaxHeight;
    // looping through all the x locations and deciding the y value
    for (unsigned int i = 0; i < heigth; ++i) {     // y
        for(unsigned int j = 0; j < width; ++j) {  // x
            double x = (double)j / ((double)width);
            double y = (double)i / ((double)heigth);
            // Typical Perlin noise
            double n = noise(10 * x, 10 * y, 0.8);
            //n is the ground added on top of the base layer (n = highest peak at point j)
            arrMaxHeight.push_back((int)(n * 255));
        }
    }
    std::wofstream fileStream;
    fileStream.open(L"GameSave/world/World.txt");
    if (fileStream.fail())
    {
        return false;
    }
    //fileStream << L"[I could put something up here but that's still in development!]" << std::endl;
    byte blockType = 0;
    std::vector<byte> arrBlockType;
    for (int i = 0; i < m_WorldSizeX; i++)
    {
        for (int j = 0; j < m_WorldSizeY; j++)
        {
            if (j > arrMaxHeight.at(i))
            {
                //block is not air
                blockType = 1;
            }
            else
            {
                //block is air
                blockType = 0;
            }
            arrBlockType.push_back(blockType);
            fileStream << blockType << "/n";
        }
    }
    fileStream.close();
    return true;
}

现在这还不算太坏,在大约5分钟内生成世界并将其发送到world.txt没有任何问题,我的加载(每行读取world.txt)需要很长时间。使用std::wifstream及其getline()函数从文本文件中完全读取所有行大约需要30多分钟。它读取所有行并将它们添加到std::vector中,然后从该向量创建"块"。块的创建在几秒钟内完成,但wifstream真的很慢。

下面是worldLoad的代码:
    std::wifstream ifileStream;
ifileStream.open("GameSave/world/World.txt");
if (ifileStream.fail())
{
    std::cout << "Could not open World.txt" << std::endl;
    return;
}
std::wcout << "LoadWorld Started";
std::wstring extractedLine;
while (!ifileStream.eof())
{
    std::getline(ifileStream, extractedLine);
    m_ArrBlockData.push_back(StringToByte(extractedLine));
    std::wcout << m_ArrBlockData.size() << "n";
}

DOUBLE2 location;
for (size_t i = 0; i < m_ArrBlockData.size(); i++)
{
    location.y = (i % m_WorldSizeY) * 16;
    if (location.y == 0)
    {
        location.x += 16;
    }
    Block *block = new Block(location, m_ArrBlockData.at(i));
    m_ArrBlocks.push_back(block);
    std::wcout << "Bock Created" << std::endl;
}

对如何优化这个有什么想法吗?我正在考虑只读取玩家周围的块类型,但这仍然需要我在能够对它们进行操作之前将所有块放入向量中。

亲切的问候,雅尼

PS: DOUBLE2是一个自定义变量,包含两个double double (double x, double y)

在你的代码中附加一个分析器,看看到底是什么很慢,我怀疑这与流(那些往往很慢)和向量有关。(当你插入数据时,他们会重新分配/移动数据)。

arrBlockType是干什么用的?随着它的增长,您可能会有很多重新分配(因为您没有预先分配它内部的任何空间)....一旦它被填满,你就再也不用它了。把它去掉,你的函数会更快。

如果可以使用boost,我建议使用它的序列化库。在使用二进制存档时,它易于使用、灵活且相对高性能。当然,还有很多选择。