【问题标题】:c++ writing and reading text file is very slow, any alternatives?c++ 读写文本文件很慢,有什么办法吗?
【发布时间】:2015-10-27 01:37:21
【问题描述】:

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

    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 是一个自定义变量,包含 2 个双精度数 DOUBLE2(double x, double y)

【问题讨论】:

  • 由于加载是您的问题,请同时提供sn-p
  • 为什么要写入文本文件而不是二进制文件?另外,尝试将所有数据放入单个vector,然后将整个数据写入文件。应该比逐字节写入快很多
  • @x29a 加载 sn-p 添加,我将reserve() 添加到我的大多数向量中,这样后推会更快,并删除循环内的所有 cout,这似乎加快了它的速度已经有点了。现在我只用块溢出我的 RAM。所以目前正在努力将块的创建移动到一个刻度函数,该函数根据玩家的位置创建新块并删除块。

标签: c++ filestream wifstream


【解决方案1】:

将分析器附加到您的代码以查看究竟是什么非常慢, 我怀疑它与流(那些往往很慢)和向量有关。 (当您插入数据时,它们会重新分配/移动数据)。

如果您事先知道大小,请在向量中保留大小。

【讨论】:

    【解决方案2】:

    arrBlockType 是干什么用的?随着它的增长,您可能会在那里进行很多重新分配(因为您没有预先分配其中的任何空间)......然后一旦它被填满,您就永远不会真正使用它。把它拿出来,你的功能会更快。

    【讨论】:

    • 我把 arrBlockType 留在了那里,因为之前的代码片段我不再使用了,很好的发现!但这不会影响加载速度吧?只有生成速度。
    • @BlaDrzz:对。但是由于我看不到你的加载代码,所以我不能谈论它。
    • 我刚刚包含了加载代码。而且我刚刚添加了m_arrBlockType 大小的预分配,但它似乎并没有对速度产生很大影响。我确实有 2 个变量保存最大宽度和高度,因此我可以将它们相乘以获得数组的大小。
    • @BlaDrzz:每次从文件中读取一行时,向std::wcout 写入一行并没有帮助。控制台很慢。
    【解决方案3】:

    如果你可以使用 boost,我建议使用它的serialization library。使用二进制存档时,它使用简单、灵活且性能相对较高。当然,还有很多选择。

    【讨论】:

    • 所以我尝试以二进制文件保存和检索文件,因此它是一个 world.bin,但该文件只会获得大约 1kb 的数据,而我的文本文件是 33.7Mb,大约有 1150 万保存在 world.txt 中的字节行,所以我只是将其简化回文本文件。我肯定会研究 boost,看看我是否可以让二进制版本正常工作。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-03-28
    • 2016-10-29
    • 1970-01-01
    • 2013-10-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多