Я пишу приложение, в котором я читаю значения из CSV-файла. Каждая строка разбивается там, где запятая хранится в векторе. Каждая строка имеет 4 значения. Затем я сохраняю каждое значение в другом векторе. Файл CSV имеет 5,795,857 строк. Поэтому в моей структуре я хочу хранить значения 4 * 5.795.857. Проблема в том, что приложение давит. Как я вижу в отладчике, я разбиваюсь примерно на линию 405.000. Я знаю, что мой компьютер немного стар, но я думаю, что он должен быть в состоянии хранить это количество значений. Я запускаю Qt5 на 32-битной WindowsXP, и у меня есть 1 ГБ оперативной памяти.
Я новичок в программировании на Qt и c ++, но как Java-разработчик, когда у меня возникают такие проблемы, я увеличиваю размер кучи. Ты думаешь это моя проблема? Если да, как я могу увеличить размер кучи в Qt5?
Это мой код, который читает файл и сохраняет его в структуре данных
std::vector < std::vector < QString> > Server::loadCsvFile( const char* path )
{
vector <QString> temp;
vector <vector <QString> > dataFlow;
string dataString;
QString row;
ifstream dataFile( path );
int stopCounter = 0;
//while((dataFile.good()) && (stopCounter < 1095))
while (dataFile.good())
{
stopCounter++;
getline( dataFile, dataString );
row = QString::fromStdString( dataString );
//cout << "counter: " << stopCounter << "\n";
QStringList rowList = row.split( "," );
for( int i=0; i < rowList.size(); i++ )
{
temp.push_back( rowList.at(i));
}
dataFlow.push_back( temp );
temp.clear();
rowList.clear();
}
dataFile.close();
dataFlow.pop_back();
return dataFlow;
}
До сих пор я вносил некоторые изменения, чтобы решить эту проблему, но ничего. Вот как это выглядит мой код знаю:
std::vector < QStringList > Server::loadCsvFile2( const char* path )
{
std::vector < QStringList > dataFlow;
QFile file(path);
if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
throw std::runtime_error("Can't open the file " +
std::string(path));
QTextStream in(&file);
int counter = 0;
while (!in.atEnd())
{
counter++;
dataFlow.emplace_back(in.readLine().split(","));
cout << counter << "\n";
}
return dataFlow;
}
В основном, std::vector
состоит из трех элементов:
Емкость — это количество элементов, которые вектор может в настоящее время содержать, и это фактический размер (в ОЗУ) вашего массива. Размер — это количество элементов, которые у вас есть в вашем векторе. Например, когда вы создаете пустой vector<int>
, его размер равен 0, его емкость равна 10 (или что-то еще, я не знаю), и массив потребляет 10 * sizeof(int)
, если ты push_back
значение, то размер равен 1, но емкость или фактический размер массива не изменились.
Но когда у вас есть 10 элементов в вашем векторе и вы пытаетесь добавить один, что-то происходит: фактический массив заполнен (vec.size() == vec.capacity()
) поэтому алгоритм должен расширить эту емкость:
20 * sizeof(int)
байт,Конечно, теперь вы можете добавить до 20 элементов, и добавление 21-го приведет к тому, что алгоритм выделит 40 элементов, а добавление 41-го приведет к 80 и т. Д.
Обычно вас не волнуют эти внутренние детали. Но когда вы добавляете много-много элементов в вектор, все становится проблематичным. Чем больше растет вектор, тем больше новых выделений и копий занимают время и занимают оперативную память. В вашей ситуации, я подозреваю, что ваша 405 001-я строка заставляет алгоритм выделять 810 000 элементов и копировать с первого на второй, и, поскольку ОЗУ работает очень мало, ваша ОС записывает его части на диск, который мертвых медленный.
Вы хотите, чтобы начальная емкость массива была достаточно большой, чтобы уменьшить вероятность перераспределения. Что вы можете сделать, это позвонить reserve
метод и дать ему достаточно большое число, чтобы избежать слишком много выделений. Тем не менее, я боюсь, что вам может не хватить оперативной памяти, чтобы выполнить этот процесс даже таким образом.
Других решений пока нет …