[英]c++ writing and reading text file is very slow, any alternatives?
I am currently writing code for a game and I'm a little bit stuck on saving and loading the level. 我目前正在为游戏编写代码,但在保存和加载关卡方面有些停留。 For writing I use this piece of code: 在编写过程中,我使用以下代码:
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;
}
Now this not too bad, generates the world in around 5 minutes and sends it to world.txt without any issues, my loading(reading world.txt line per line) however takes ages. 现在,这还算不错,在大约5分钟内生成了一个世界并将其发送到world.txt,没有任何问题,但是我的加载(每行读取world.txt行)却需要花费很多时间。 Around 30+ minutes to fully read all the lines from the text file using std::wifstream
and its getline()
function. 大约需要30分钟以上的时间,才能使用std::wifstream
及其getline()
函数从文本文件中完全读取所有行。 It reads all the lines and adds them to a std::vector
and later creates "blocks" from this vector. 它读取所有行并将它们添加到std::vector
,然后从该向量中创建“块”。 The creation of the blocks is done in a few seconds but the wifstream is really slow. 块的创建在几秒钟内完成,但是wifstream确实很慢。
Here's the code for worldLoad: 这是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;
}
Any idea on how to optimise this? 关于如何优化这一点的任何想法? I was thinking about only reading blockTypes around the player but that would still require me putting all the blocks into a vector before being able to operate on them. 我在考虑只读取播放器周围的blockType,但是仍然需要我将所有块放入向量中,然后才能对其进行操作。
Kind regards, Jannes 亲切的问候,Jannes
PS: DOUBLE2 is a custom variable holding 2 doubles DOUBLE2(double x, double y) PS:DOUBLE2是一个自定义变量,包含2个double的DOUBLE2(double x,double y)
Attach a profiler to your code to see what exactly is very slow, I suspect that it is related to the streams (those tend to be slow), and the vectors. 将事件探查器附加到您的代码中,以查看到底是什么非常慢,我怀疑它与流(那些往往很慢)和向量有关。 (They re-allocate / move data around a lot when you are inserting data). (当您插入数据时,它们会大量重新分配/移动数据)。
If you know the size beforehand, reserve the size in the vector. 如果事先知道大小,请在向量中保留大小。
What is arrBlockType
for? arrBlockType
有什么用? You likely have a lot of reallocations there as it grows (because you do not preallocate any space inside it).... and then you never actually use it once it's filled. 随着它的增长,您可能会在其中进行很多重新分配(因为您没有在其中预先分配任何空间)....然后,它一旦被填充就永远不会真正使用它。 Take that out and your function will be faster. 删除它,您的功能将更快。
If you can use boost, I would suggest using its serialization library . 如果可以使用boost,我建议使用其序列化库 。 It is simple to use, flexible, and relatively high-performance when using the binary archive. 使用二进制归档文件时,它易于使用,灵活且具有较高的性能。 There are, of course, many alternatives. 当然,还有许多替代方案。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.