Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Общие вопросы > Быстрая сохранение\загрузка


Автор: XperT 20.1.2010, 13:14
Здравствуйте,

Есть программа которая сохраняет данные в локальные базы данных (в формате Absolute Database). В принципе как таковой необходимости использования баз данных нету, потому что программа при открытии проекта загружает все данные обычным Селектом, а при сохранении обновляет их. Был взят этот метод, потому что легко сохранять данные определённой стркутуры и в случае необходимости изменять саму структуру.

Но вот проблема в том, что сохранение и загрузка данных происходит довольно таки медленно и это ощущается на проектах в 2000+ записей. Хочу поменять формат на обычные текстовые файлы, но теперь возникает проблема выбора формата сохранения данных.

Первое, что пришло на ум использовать формат XML, но я не уверен на сколько быстро будет происходить работа з данным форматом. Потому у меня есть несколько вопросов (возможно кто-то стыкался с подобной проблемой и готов поделиться своими знаниями):
- рациональным ли есть использования XML формата сохранения данных в плане скорости?
- если да, то что лучше: использовать готовые парсеры XML или можно всё парсить вручную используя регулярки (опять таки в плане скорости)
- возможно есть готовые решения и мне не придётся изобретать велосипед?

Заранее благодарен за советы и указания smile

Автор: RockClimber 20.1.2010, 16:03
Цитата(XperT @  20.1.2010,  13:14 Найти цитируемый пост)
- рациональным ли есть использования XML формата сохранения данных в плане скорости?

Ну конечно же нет. Если надо совсем быстро - то бинарные данные. Помнится, у Джоэла Спольски была статья на эту тему с примерами из Excel (он был одним из разработчиков). В ранних версиях Excel использовалась функция, которая писала произвольный кусок оперативной памяти на диск. Джоэл даже приводил какие-то расчеты вроде, XML проигрывает этой функции раз в 30... 
Статью искать лень.

Автор: XperT 20.1.2010, 18:00
Цитата(RockClimber @ 20.1.2010,  16:03)
Цитата(XperT @  20.1.2010,  13:14 Найти цитируемый пост)
- рациональным ли есть использования XML формата сохранения данных в плане скорости?

Ну конечно же нет. Если надо совсем быстро - то бинарные данные. Помнится, у Джоэла Спольски была статья на эту тему с примерами из Excel (он был одним из разработчиков). В ранних версиях Excel использовалась функция, которая писала произвольный кусок оперативной памяти на диск. Джоэл даже приводил какие-то расчеты вроде, XML проигрывает этой функции раз в 30... 
Статью искать лень.

Спасибо, покопаю в эту сторону. Но мне кажется добавлять новые параметры будет проблематично при таком подходе...

З.Ы. И еще хотел спросить: скорость чтения и записи через текстовых файлов TStringList сильно уступает обычному readln/writeln?

Автор: Dom 20.1.2010, 19:11
Раньше тоже использовал ХМЛ для хранения данных, но с ростом размера файла пришлось отказаться. Много памяти расходовалось из-за специфической структуры данных. Кстати есть очень шустрые парсеры ХМЛ (например NativeXML, которым пользовался раньше). Не знаю насколько рационально, но сейчас я использую такой подход к хранению файлов в бинарном формате. Может изобретаю велосипед и кто-то предложит лучше.

Сперва создаю и сохраняю в файл массив состоящий из записей, каждая из которых хранит данные об определенной секции в файле (имя секции, начальная позиция в файле, размер секции, версия данных секции). За сохранение/загрузку каждого раздела данных отвечает своя процедура, соответствующей версии. Т.е. если надо что-то изменить в процедуре записи/чтения данных, то надо продублировать существующую процедуру, внести в нее желаемые изменения и присвоить ей следующий по порядку номер версии. Надеюсь понятно изложил. 

Кстати если будут другие идеи получше, то тоже буду рад выслушать.

Автор: amsoft 20.1.2010, 20:41
Цитата(XperT @  20.1.2010,  21:00 Найти цитируемый пост)
З.Ы. И еще хотел спросить: скорость чтения и записи через текстовых файлов TStringList сильно уступает обычному readln/writeln?


Особой разницы я не увидел (один и тот же текстовый файл (около 3000 строк) загружал обоими способами) - оба работают медленно, тоже хочу найти быстрый вариант загрузки.

Автор: XperT 21.1.2010, 00:45
Такс... пока что сошлись на том, что бинарные файлы быстрее всего. Но тут страдает удобство их использования (в основном в плане расширения сохраняемых параметров, а потому главное с самого начала нигде не лоханутся).

Возможно у кого то есть еще варианты в которых скорость/удобство использования имеют самые оптимальные значения?

Автор: ~FoX~ 21.1.2010, 07:37
Цитата(XperT @  20.1.2010,  14:14 Найти цитируемый пост)
- рациональным ли есть использования XML формата сохранения данных в плане скорости?

Нет, за счет чего, вы думаете, должна подняться скорость? БД выдает вам рекордсет на основе уже индексированных данных, нет накладных расходов на сортировку, фильтрацию, парсинг и т.д. В случае с ХМЛ 1. вся работа по описанию, индексации, выдачи/получении, и т.д. ляжет на вас. 2. Драйвер БД формирует рекордсет непосредственно в памяти и/или свопе, что в разы превосходми по скорости постоянное дергание винта. 

Цитата(XperT @  20.1.2010,  19:00 Найти цитируемый пост)
З.Ы. И еще хотел спросить: скорость чтения и записи через текстовых файлов TStringList сильно уступает обычному readln/writeln?

Зависит от загруженности системы.... TStrinGlist и еже с ними используют потоки для сохранения, соответственно на каждую итерацию возникает ожидание очереди...

Может быть стоит подумать над оптимизвацией имеющийся БД, например выбирать только те данные которые в данный момент нужны, или создать нужное количество словарей, а в главной таблице хранить лишь ссылки(key field например) на данные в этих словарях (связанные таблицы), тогда в таблице будут только числа, что сильно ускорит выдачу результатов со стороны драйвера, но придется все формировать руками на стороне клиента...

З.Ы.: 2000 записей в таблице, ИМХО капейки для нормально написанной БД  smile  

Автор: XperT 21.1.2010, 19:42
Цитата(~FoX~ @ 21.1.2010,  07:37)
Цитата(XperT @  20.1.2010,  14:14 Найти цитируемый пост)
- рациональным ли есть использования XML формата сохранения данных в плане скорости?

Нет, за счет чего, вы думаете, должна подняться скорость? БД выдает вам рекордсет на основе уже индексированных данных, нет накладных расходов на сортировку, фильтрацию, парсинг и т.д. В случае с ХМЛ 1. вся работа по описанию, индексации, выдачи/получении, и т.д. ляжет на вас. 2. Драйвер БД формирует рекордсет непосредственно в памяти и/или свопе, что в разы превосходми по скорости постоянное дергание винта. 

Цитата(XperT @  20.1.2010,  19:00 Найти цитируемый пост)
З.Ы. И еще хотел спросить: скорость чтения и записи через текстовых файлов TStringList сильно уступает обычному readln/writeln?

Зависит от загруженности системы.... TStrinGlist и еже с ними используют потоки для сохранения, соответственно на каждую итерацию возникает ожидание очереди...

Может быть стоит подумать над оптимизвацией имеющийся БД, например выбирать только те данные которые в данный момент нужны, или создать нужное количество словарей, а в главной таблице хранить лишь ссылки(key field например) на данные в этих словарях (связанные таблицы), тогда в таблице будут только числа, что сильно ускорит выдачу результатов со стороны драйвера, но придется все формировать руками на стороне клиента...

З.Ы.: 2000 записей в таблице, ИМХО капейки для нормально написанной БД  smile

З базами данных работаю давно, как грамотно составить таблицы тоже знаю не по наслышке, так что работают они прилично быстро. Скорость не во время Селекстов огорчает, а во время по очередному считыванию записей и сохранению их в динамический массив. 

Тесты примерно такие:
Запрос: SELECT * FROM table ORDER BY field - время выполнения примерно 3 мс
Копирование записей в массив - время выполнения примерно 4 с

Это на таблице в 2617 записей и в БД размером 50 Мб (но там немного меньше будет, если очистить логи).

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

работать сразу с данными не могу, потому что будет еще медленнее (очень много операций которые обрабатывают все записи, потому работать с массивом рекордов быстрее чем делать кучу запросов в БД).

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