filestream — c ++ написание и чтение текстовых файлов очень медленные, есть альтернативы?

В настоящее время я пишу код для игры, и я немного застрял на сохранении и загрузке уровня. Для написания я использую этот кусок кода:

    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 на строку), однако, занимает много времени. Около 30 минут, чтобы полностью прочитать все строки из текстового файла, используя std::wifstream И его getline() функция. Он читает все строки и добавляет их в std::vector и позже создает «блоки» из этого вектора. Создание блоков выполняется за несколько секунд, но вайфстрим очень медленный.

Вот код для 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;
}

Есть идеи, как это оптимизировать? Я думал только о том, чтобы читать blockTypes вокруг плеера, но это все равно потребует от меня помещения всех блоков в вектор, прежде чем я смогу работать с ними.

С уважением,
Ианний

PS: DOUBLE2 — это пользовательская переменная, содержащая 2 double DOUBLE2 (double x, double y)

0

Решение

Присоедините профилировщик к своему коду, чтобы увидеть, что именно очень медленно,
Я подозреваю, что это связано с потоками (которые имеют тенденцию быть медленными) и векторами. (Они перераспределяют / перемещают данные во время вставки данных).

Если вы заранее знаете размер, зарезервируйте размер в векторе.

0

Другие решения

Что такое arrBlockType за? Скорее всего, у вас там много перераспределений по мере роста (потому что вы не выделяете в них никакого пространства) …. и тогда вы никогда не будете использовать его, когда он заполнится. Уберите это, и ваша функция будет быстрее.

0

Если вы можете использовать повышение, я бы предложил использовать его библиотека сериализации. Он прост в использовании, гибок и относительно высокопроизводителен при использовании бинарного архива. Есть, конечно, много альтернатив.

0
По вопросам рекламы [email protected]