Есть программа, в которой открывается файл определенного формата. Из файла данные пихаются в таблицу. Однако файлы бывают такие большие, что превышают 50мб. И когда открываешь такой файл, программа мин 15 думает, обрабатывая строки, а потом виснет, так как не может нарисовать 50000 строк таблицы сразу.
Может быть подскажете алгоритм обработки таких ситуаций?
Таблица: QTableWidget
Интересная задача (Qt4)
Модератор: Модераторы разделов
-
Assuri
- Сообщения: 678
- Статус: #include <brain.h>
- ОС: Fedora 12
-
TwisT
- Сообщения: 265
- ОС: Debian
Re: Интересная задача
Наверное файл читается в цикле по несколько байт :-)
Не удивительно что он 15 минут обрабатывается, можно замутить буфер и читать большими кусками
например по несколько метров,а потом из памяти выбирать, все быстрее будет. рекомендую подробнее посмотреть ввод/вывод в qt
Ну как вариант использовать многопоточность:
1. Созданный поток в фоне грузит содержимое файла в таблицу, причем приоритет его можно сделать ниже среднего чтобы систему не сильно тормозил
2. Создать несколько потоков, каждый будет обрабатывать свою часть файла.
Не удивительно что он 15 минут обрабатывается, можно замутить буфер и читать большими кусками
например по несколько метров,а потом из памяти выбирать, все быстрее будет. рекомендую подробнее посмотреть ввод/вывод в qt
Ну как вариант использовать многопоточность:
1. Созданный поток в фоне грузит содержимое файла в таблицу, причем приоритет его можно сделать ниже среднего чтобы систему не сильно тормозил
2. Создать несколько потоков, каждый будет обрабатывать свою часть файла.
Linux user #432536.
-
sergio
- Сообщения: 436
- Статус: Интересующийся новичок
- ОС: Debian GNU/Linux 4 & 5
Re: Интересная задача
-DooM- писал(а): ↑11.10.2007 08:36Есть программа, в которой открывается файл определенного формата. Из файла данные пихаются в таблицу. Однако файлы бывают такие большие, что превышают 50мб. И когда открываешь такой файл, программа мин 15 думает, обрабатывая строки, а потом виснет, так как не может нарисовать 50000 строк таблицы сразу.
Таблица: QTableWidget
Как минимум две стадии:
1) программа обрабатывает строки считывая файл
2) программа долго рисует и не может нарисовать
Неплохо бы уточнить, как процесс происходит, и какая из жрет столько времени; может заодно выяснится по ходу дела, что вы по строке считываете и добавляете в таблицу, и она на каждое добавление пытается обновить лэйаут и отображение =)
1) в каком формате файл?? почему так тугодумно считывается (машина какая? для пентиума 50Мег 50к строк за 15 минут может и нормально...)? куда складываются строки? В ваши структуры для хранения, или сразу в табличные объекты?
2) хорошая таблица для больших объемов не должна пытаться "рисовать" все, что в нее положили, а только то, что попадает во viewport; но есть некоторые тонкости, например не рассчитав рендеринг всех строк, она может только весьма приблизительно изобразить полосу прокрутки; если стоит какое-то "автоформатирование" ширины колонок (в зависимости от содержимого ячеек) - она начнет просчитывать ширину отображения для всех ячеек - это уже почти равноценно рисованию всех 50000 строк =); смотрим, есть возможность виджет конфигурировать на эту тему; можно ли заставить его работать в внешними структурами данных; если можно - есть над чем думать, если нет и никакую автоматику отключить не получается - остается лезть в нутро и смотреть где там дубы растут и что переделывать...
Debian GNU/Linux 4 -- AMD Athlon64 3000+ / Asus 7600GS -- Gnome
Debian GNU/Linux 5 -- Dell (Vostro) 500 (Celeron M560 / iGM965) -- Gnome
Debian GNU/Linux 5 -- Dell (Vostro) 500 (Celeron M560 / iGM965) -- Gnome
-
Assuri
- Сообщения: 678
- Статус: #include <brain.h>
- ОС: Fedora 12
Re: Интересная задача
2) программа долго рисует и не может нарисовать
Неплохо бы уточнить, как процесс происходит, и какая из жрет столько времени; может заодно выяснится по ходу дела, что вы по строке считываете и добавляете в таблицу, и она на каждое добавление пытается обновить лэйаут и отображение =)
У меня так и было -исправил. Стало быстрее, но надо еще быстрее.
1) в каком формате файл?? почему так тугодумно считывается (машина какая? для пентиума 50Мег 50к строк за 15 минут может и нормально...)? куда складываются строки? В ваши структуры для хранения, или сразу в табличные объекты?
Текстовый файл. Машина мощная. Теперь весь файл считывается в одну большую переменную QString, после чего эта переменная разделяется на куски и эти куски пихаются в таблицу.
2) хорошая таблица для больших объемов не должна пытаться "рисовать" все, что в нее положили, а только то, что попадает во viewport; но есть некоторые тонкости, например не рассчитав рендеринг всех строк, она может только весьма приблизительно изобразить полосу прокрутки; если стоит какое-то "автоформатирование" ширины колонок (в зависимости от содержимого ячеек) - она начнет просчитывать ширину отображения для всех ячеек - это уже почти равноценно рисованию всех 50000 строк =); смотрим, есть возможность виджет конфигурировать на эту тему; можно ли заставить его работать в внешними структурами данных; если можно - есть над чем думать, если нет и никакую автоматику отключить не получается - остается лезть в нутро и смотреть где там дубы растут и что переделывать...
Вот именно это я и хочу реализовать, только вот пока не знаю как
-
sergio
- Сообщения: 436
- Статус: Интересующийся новичок
- ОС: Debian GNU/Linux 4 & 5
Re: Интересная задача
1) Реализацию КуСтринг знаете? Для std::string реализация - непрерывный кусок памяти. При добавлении данных свыше стартовых ~512 символов, емкость удваивается, память перераспределяется, данные копируются. Если КуСтринг сделан также и вы не зарезервировали size-of-file памяти - то имеете прорву лишних перераспределений и копирований при загрузке.
2) Что значит разделяется на куски и куски пихаются? Если "разделитель" возвращает строку с "куском" +1 копирование. Если при "пихании" таблица копирует данные - +1 копирование (если CoW в строках не спасает).
Вот именно это я и хочу реализовать, только вот пока не знаю как
Два подхода: мучиться дальше с загрузкой файла. 50мег - объем не смертельный, можно и сделать чтоб нормально крутилось. Подход второй - подойти по принципу БД.
Что есть "текстовый файл"? они разные бывают. CSV? DBF?
Если ДБФ-подобное - то никто не заставляет его весь затаскивать в память, можно считывать только то, что на экране. Полосу прокрутки настроить исходя из общего числа записей в файле (оно там в заголовке файла обычно хранится). Ну, это тупой вариант, чуть умнее там надо небольшой кэшик для записей... Кроме того, смотрим сразу классы Куте для работы с базами - там наверняка есть готовая табличка, и модулек для ДБФ файлов, который к ней присоединяецо.
Debian GNU/Linux 4 -- AMD Athlon64 3000+ / Asus 7600GS -- Gnome
Debian GNU/Linux 5 -- Dell (Vostro) 500 (Celeron M560 / iGM965) -- Gnome
Debian GNU/Linux 5 -- Dell (Vostro) 500 (Celeron M560 / iGM965) -- Gnome
-
Assuri
- Сообщения: 678
- Статус: #include <brain.h>
- ОС: Fedora 12
Re: Интересная задача
Почти сделал все, что хотел с самого начала: рисуется то, что видно. Однако есть проблема: как мне сделать так, чтобы скроллбар мог двигаться вниз независимо от количества нарисованных строк? verticalScrollBar()->setRange,setMinimum - не работают 
-
d_n_k
- Сообщения: 636
- ОС: Gentoo GNU/Linux
Re: Интересная задача
сории за офф топик,но
QT не подддерживает model-view для таблиц?
так же не понятно зачем именно таблица, почему не выбрал ListView.
таблица создается с заданой высотой и шириной, а ListView поддерживает динамическое обновление.
QT не подддерживает model-view для таблиц?
так же не понятно зачем именно таблица, почему не выбрал ListView.
таблица создается с заданой высотой и шириной, а ListView поддерживает динамическое обновление.
все сказанное есть имхо...
-
vantaker
- Сообщения: 166
Re: Интересная задача
Вот именно это я и хочу реализовать, только вот пока не знаю как
Такую штуку часто называют virtual grid. Стоит наверна погуглить по этому названию