Интересная задача (Qt4)

Модератор: Модераторы разделов

Аватара пользователя
Assuri
Сообщения: 678
Статус: #include <brain.h>
ОС: Fedora 12

Интересная задача

Сообщение Assuri »

Есть программа, в которой открывается файл определенного формата. Из файла данные пихаются в таблицу. Однако файлы бывают такие большие, что превышают 50мб. И когда открываешь такой файл, программа мин 15 думает, обрабатывая строки, а потом виснет, так как не может нарисовать 50000 строк таблицы сразу.

Может быть подскажете алгоритм обработки таких ситуаций?

Таблица: QTableWidget
Спасибо сказали:
TwisT
Сообщения: 265
ОС: Debian

Re: Интересная задача

Сообщение TwisT »

Наверное файл читается в цикле по несколько байт :-)
Не удивительно что он 15 минут обрабатывается, можно замутить буфер и читать большими кусками
например по несколько метров,а потом из памяти выбирать, все быстрее будет. рекомендую подробнее посмотреть ввод/вывод в qt
Ну как вариант использовать многопоточность:
1. Созданный поток в фоне грузит содержимое файла в таблицу, причем приоритет его можно сделать ниже среднего чтобы систему не сильно тормозил
2. Создать несколько потоков, каждый будет обрабатывать свою часть файла.
Linux user #432536.
Спасибо сказали:
sergio
Сообщения: 436
Статус: Интересующийся новичок
ОС: Debian GNU/Linux 4 & 5

Re: Интересная задача

Сообщение sergio »

-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
Спасибо сказали:
Аватара пользователя
Assuri
Сообщения: 678
Статус: #include <brain.h>
ОС: Fedora 12

Re: Интересная задача

Сообщение Assuri »

2) программа долго рисует и не может нарисовать
Неплохо бы уточнить, как процесс происходит, и какая из жрет столько времени; может заодно выяснится по ходу дела, что вы по строке считываете и добавляете в таблицу, и она на каждое добавление пытается обновить лэйаут и отображение =)

У меня так и было -исправил. Стало быстрее, но надо еще быстрее.

1) в каком формате файл?? почему так тугодумно считывается (машина какая? для пентиума 50Мег 50к строк за 15 минут может и нормально...)? куда складываются строки? В ваши структуры для хранения, или сразу в табличные объекты?

Текстовый файл. Машина мощная. Теперь весь файл считывается в одну большую переменную QString, после чего эта переменная разделяется на куски и эти куски пихаются в таблицу.
2) хорошая таблица для больших объемов не должна пытаться "рисовать" все, что в нее положили, а только то, что попадает во viewport; но есть некоторые тонкости, например не рассчитав рендеринг всех строк, она может только весьма приблизительно изобразить полосу прокрутки; если стоит какое-то "автоформатирование" ширины колонок (в зависимости от содержимого ячеек) - она начнет просчитывать ширину отображения для всех ячеек - это уже почти равноценно рисованию всех 50000 строк =); смотрим, есть возможность виджет конфигурировать на эту тему; можно ли заставить его работать в внешними структурами данных; если можно - есть над чем думать, если нет и никакую автоматику отключить не получается - остается лезть в нутро и смотреть где там дубы растут и что переделывать...

Вот именно это я и хочу реализовать, только вот пока не знаю как :(
Спасибо сказали:
sergio
Сообщения: 436
Статус: Интересующийся новичок
ОС: Debian GNU/Linux 4 & 5

Re: Интересная задача

Сообщение sergio »

-DooM- писал(а):
11.10.2007 13:16
1) в каком формате файл??

Текстовый файл. Машина мощная. Теперь весь файл считывается в одну большую переменную QString, после чего эта переменная разделяется на куски и эти куски пихаются в таблицу.

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
Спасибо сказали:
Аватара пользователя
Liksys
Сообщения: 2910

Re: Интересная задача

Сообщение Liksys »

-DooM-, да не секрет, что за файл :)
Спасибо сказали:
Аватара пользователя
Assuri
Сообщения: 678
Статус: #include <brain.h>
ОС: Fedora 12

Re: Интересная задача

Сообщение Assuri »

Почти сделал все, что хотел с самого начала: рисуется то, что видно. Однако есть проблема: как мне сделать так, чтобы скроллбар мог двигаться вниз независимо от количества нарисованных строк? verticalScrollBar()->setRange,setMinimum - не работают :(
Спасибо сказали:
d_n_k
Сообщения: 636
ОС: Gentoo GNU/Linux

Re: Интересная задача

Сообщение d_n_k »

сории за офф топик,но

QT не подддерживает model-view для таблиц?


так же не понятно зачем именно таблица, почему не выбрал ListView.
таблица создается с заданой высотой и шириной, а ListView поддерживает динамическое обновление.
все сказанное есть имхо...
Спасибо сказали:
vantaker
Сообщения: 166

Re: Интересная задача

Сообщение vantaker »

Вот именно это я и хочу реализовать, только вот пока не знаю как :(


Такую штуку часто называют virtual grid. Стоит наверна погуглить по этому названию
Спасибо сказали:
Аватара пользователя
Liksys
Сообщения: 2910

Re: Интересная задача

Сообщение Liksys »

Уже нашли другой подход.
Спасибо сказали: