Russian Qt Forum

Qt => Общие вопросы => Тема начата: JamS007 от Май 06, 2010, 22:24



Название: Максимально быстрое сохранение нескольких контейнеров
Отправлено: JamS007 от Май 06, 2010, 22:24
Здравствуйте,

имються несколько контейнреных классов, QHash, QMultiHash и QList. По ходу выполнения програмы, в них часто меняються значения, и их нужно записывать на диск. Все контейнеры записываються в один файл, размером около 100 кб. Проблема в том, что сохранение происходит достаточно часто, и каждый раз переписывать файл по новому ради одного значения несколько накладно, тем более нужна оперативность.

Посоветуйте какой-нибудь способ оптимизирвать сохранение этих контейнеров.

П.С.
Рассматривал идею сохранить информацию в файле последовательно, и при изменении информации перемещаться в файле в позицию, где произошли изменения и сохранять только изменившиеся байты, но эта идея не совсем подходит. Дело в том, что используеться контейнер QHash, а в нем реализована зависимость типа "Пользователь - Информация". Если добавить/удалить/переименовать  пользователя, то вышеупомянутый файл становиться некорректным, так как перемещение по файлу будет происходить в некорректную позицию.


Название: Re: Максимально быстрое сохранение нескольких контейнеров
Отправлено: Marat(Qt) от Май 06, 2010, 22:37
я бы sqlite использовал для такой задачи.


Название: Re: Максимально быстрое сохранение нескольких контейнеров
Отправлено: JamS007 от Май 06, 2010, 22:42
никогда не использовал, можно подробней?
Где можно почитать или посмотреть пример использования?

Другие идеи тоже принимаються...


Название: Re: Максимально быстрое сохранение несколь
Отправлено: Marat(Qt) от Май 06, 2010, 23:40
Дык, это же базы данных. создаем табличку и пишем в нее. просто для sqlite не нужно сервера, он прямо в программу вклеивается, а данные хранятся в .sql файле, в формате понятном самому sqlite. Просто я думаю если использовать БД, то там явно не производится полная перезапись исходного файла.
С другой стороны стал бы я использовать QHash и ему подобные? Ну пожалуй это сильно от задачи зависит. А вообще я бы запросами ограничился, чтобы и читать данные не все сразу, а только по необходимости. Но, думаю не сложно будет считать всю таблицу в контейнер а записывать в базу(т.е. файл) только то, что нужно, запросами типа update.


Название: Re: Максимально быстрое сохранение нескольких контейнеров
Отправлено: Tonal от Май 07, 2010, 07:42
Замеры проводил насколько тормозит?
Имеет ли смысл это оптимизировать?

Если таки имеет, то самое простое решение - оптимизировать формат хранения (перейти с *.ini или XML на бинарную сериализацию Qt, например).
Следующее - выделить файл под каждый контейнер.
Следующее - выделить отдельный поток для сохранения.
Далее - работа вместо простых файлов с базами данных (тот же sqlite, bsddb или post++).

Но конкретные решения, в любом случае, зависят от общей задачи и критичности данных. :)


Название: Re: Максимально быстрое сохранение нескольких контейнеров
Отправлено: Igors от Май 07, 2010, 14:40
100К не тот объем который должен тормозить. Можно попробовать писать сначала в память (напр. QBuffer) а потом одним write в файл (его надо держать открытым). Ну и разнообразные игры с числом/частотой сохранений: хранить счетчик несохраненных, проверяться по таймеру и.т.п


Название: Re: Максимально быстрое сохранение нескольких контейнеров
Отправлено: JamS007 от Май 07, 2010, 16:57
Просто пишу программу-сервер, которая должна частенько принимать и обрабатывать информацию от клиентов. Информация важная, поэтому, в случае сбоя с электро-питанием желательно иметь максимально свежую версию данных. 100 кб может и не сильно тормозить будет, но в моем случае эти 100 кб множаться на количество клиентов, а если их будет ~50 то это уже 5 мб, а если инфоримация будет менятся с частотой в 1-3 секунды, то это уже напряжно...

К БД не очень хочу привязываться, дело в том, что в контейнерах мне удобней хранить и синхронизировать информацию разных типов, бывает и такая, для которой БД-таблицу придумать сложно... а если и можно то нужно создавать 3-4 таблицы и потом стараться синхронизировать уже их... Во вторых, форматы свободных БД уже давно известны всем желающим, и каждый может их прочитать, как впрочем в случае и  сплатными... Я же  не хочу, чтоб информация была доступна третьим лицам.

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

Пришла в голову идея записывать все изменения в другой файл, размером... пусть будет 5-10 кб... Тут можна писать прямо в конец файла, и только новые изменения, в этом прирост скорости. А позже, в зависимости от нужды, переносить эти измеенения в основной файл.

Коллеги, прокоментируйте идею...


Название: Re: Максимально быстрое сохранение нескольких контейнеров
Отправлено: Igors от Май 07, 2010, 17:19
Пришла в голову идея записывать все изменения в другой файл, размером... пусть будет 5-10 кб... Тут можна писать прямо в конец файла, и только новые изменения, в этом прирост скорости. А позже, в зависимости от нужды, переносить эти измеенения в основной файл.

Коллеги, прокоментируйте идею...
Мне нравится. Др. словами Вы записываете "скрипт" изменений а потом "выполняете" его. Идейно. Операции вставки/удаления тоже должны фиксироваться. Вопрос со скоростью/надежностью все же остается открытым. Файлы надо держать открытыми. Делать flush после каждой записи - накладно. Иначе можно что-то потерять - вероятно лучше с этим примириться, делая flush по таймеру.


Название: Re: Максимально быстрое сохранение нескольких контейнеров
Отправлено: _govorilka от Май 07, 2010, 20:33
+1 про SQLite.

Мне тоже кажется, что задача сводится к использовать баз данных. Если пишется сервер, то вместо SQLite можно использовать, что посерьезнее (MySQL, PostgreSQL). SQL серверы специально предназначены для подобных задач.

Хранение информации разных типов... Можно сделать всего лишь две таблицы... в одной хранить "объекты", в другой "атрибуты, этих объектов".

Хотя, если работать с файлами, можно придумать свою систему баз данных, свой удобный SQL...


Название: Re: Максимально быстрое сохранение нескольких контейнеров
Отправлено: Marat(Qt) от Май 08, 2010, 10:05
Данные разных типов и "все такое" - это вроде как sqlite - он не типизирован.
Не хотите чтобы ваши данные кто-то мог прочитать? Ну я бы тогда права на файл правильно выставил просто. А вообще sqlite тут вам не особо поможет - шифрования в нем нет. Но есть ведь другие СУБД и люди, которые в них разбираются. Я вот не знаю, но надеюсь что в Postgre есть шифрование. В общем если уж речь идет о сервере, то на мой взгляд вам лучше либо читать книги о разработке и проектировании СУБД и делать по образу и подобию (ибо в вашем случае это близко к вашим требованием), либо брать готовую СУБД и учиться хранить в ней информацию так, чтобы все было быстро, удобно и безопасно.


Название: Re: Максимально быстрое сохранение нескольких контейнеров
Отправлено: crossly от Май 08, 2010, 11:22
Цитировать
К БД не очень хочу привязываться, дело в том, что в контейнерах мне удобней хранить и синхронизировать информацию разных типов, бывает и такая, для которой БД-таблицу придумать сложно... а если и можно то нужно создавать 3-4 таблицы и потом стараться синхронизировать уже их... Во вторых, форматы свободных БД уже давно известны всем желающим, и каждый может их прочитать, как впрочем в случае и  сплатными... Я же  не хочу, чтоб информация была доступна третьим лицам.
По мимо sqlite есть и другие встраиваемые БД .... например firebird ... в котором изначально заложена возможность шифрования (правда только под винду).... только нету реализации..... при желании дописать функции шифрования/дешифрования не сложно.... когда то развлекался подобным образом... :)


Название: Re: Максимально быстрое сохранение нескольких контейнеров
Отправлено: _govorilka от Май 08, 2010, 17:50
Про PostgreSQL написано тут:
http://www.postgresql.org/docs/8.4/interactive/encryption-options.html

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