Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > С/С++: Кроссплатформенное программирование, Qt/Gtk+/wxWidgets > Загрузка большого файла в QStringList


Автор: Matematik 25.5.2009, 11:08
Как быстро загрузить файл в QStringList?
Пробую на файле 50мб с 2'500'000 (два миллиона с половинкой) строк
Код

void MainWindow::click_button()
{
    QFile File("1.txt");
    if (File.open(QIODevice::ReadOnly))
    {
        QTime myTimer;
        myTimer.start();
        QStringList Buffer;
        while (!File.atEnd())
        {
            Buffer.append(File.readLine());
        }
        int nMilliseconds = myTimer.elapsed();
        QString str = QString( "Loaded %1 lines at %2 ms" )
                                .arg( Buffer.length() )
                                .arg( nMilliseconds );
        QMessageBox::information(this, "time-", str);
    }
    File.close();

Жму кнопку первый раз - 5сек, второй - 10сек. Почему-то получается дольше.
И еще, после закрытия QMessageBox::information() MainWindow зависает на полсекунды.
Что делаю не так?

Qt только начал изучать и само собой сравниваю с Delphi, который неплохо знаю.

Например в Delphi таким же методом добавления
Код

procedure TForm1.Button2Click(Sender: TObject);
var
  t : cardinal;
  s : TStringList;
  f : TextFile;
  z : AnsiString;
begin
  t := GetTickCount;
  AssignFile(f, '1.txt');
  Reset(f);
  s := TStringList.Create;
  while not eof(f) do
  begin
    Readln(f, z);
    s.Add(z);
  end;
  t := GetTickCount - t;
  // 2сек
  ShowMessage(Format('Loaded %d lines at %d ms', [s.Count, t]));
  s.Free;
  CloseFile(f);
end;

Обрабатывает стабильно 2сек без скачков в стороны.
Если делать встроенным методом TStringList.LoadFromFile() - грузит чуть меньше секунды
Код

procedure TForm1.Button1Click(Sender: TObject);
var
  t : cardinal;
  s : TStringList;
begin
  t := GetTickCount;
  s := TStringList.Create;
  s.LoadFromFile('1.txt');
  t := GetTickCount - t;
  // <1сек
  ShowMessage(Format('Loaded %d lines at %d ms', [s.Count, t]));
  s.Free;
end;

Автор: SABROG 25.5.2009, 13:58
Лучше используй QTextStream.

Кстати TStringList вылетает с исключением гораздо раньше, чем успевает закончится память.

Автор: andrew_121 26.5.2009, 14:20
Matematik, Не понятно почему с каждым кликом дольше.
QStringList - это QList<QString>. Добавляет он быстро.
Поэкспериментируй с QVector<QString>. Но векторы плохо подходят для частого изменения размера. По этому, подумай как ты можешь задать ему размер до загрузки.

Добавлено через 58 секунд
Цитата(SABROG @  25.5.2009,  13:58 Найти цитируемый пост)
Лучше используй QTextStream.

Не соглашусь. Экспериментально установил что он работает тяжелее.

Автор: just_geek 26.5.2009, 16:20
А зачем часто менять размер QVector ? сделать reserve равный размеру файла и усе... 

А текущее решение вообще какое-то не оптимальное, имхо. Будет дикая фрагментация памяти.

Автор: andrew_121 26.5.2009, 18:13
Цитата(andrew_121 @  26.5.2009,  14:20 Найти цитируемый пост)
По этому, подумай как ты можешь задать ему размер до загрузки.


just_geek, А я разве об этом не упомянул?  smile 

Цитата(just_geek @  26.5.2009,  16:20 Найти цитируемый пост)
А текущее решение вообще какое-то не оптимальное, имхо. Будет дикая фрагментация памяти. 

Это уже другой вопрос.

Добавлено через 51 секунду
Цитата(just_geek @  26.5.2009,  16:20 Найти цитируемый пост)
сделать reserve равный размеру файла и усе... 

А вот с этого места по подробней плиз...

Автор: just_geek 26.5.2009, 20:53
Цитата

сделать reserve равный размеру файла и усе... 

ой, ну я гоню smile

Проще помойму загнать все в один массив, а потом только сохранить указатели на строки и все.

Автор: SABROG 26.5.2009, 21:53
В принципе не мудрено почему медленно, Qt каждую строку в юникод переводит.

Автор: andrew_121 27.5.2009, 01:45
Цитата(SABROG @  26.5.2009,  21:53 Найти цитируемый пост)
В принципе не мудрено почему медленно, Qt каждую строку в юникод переводит.

Гы smile Внатуре smile 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)