Russian Qt Forum
Ноябрь 29, 2024, 02:18 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: Максимально быстрое сохранение нескольких контейнеров  (Прочитано 6362 раз)
JamS007
Гость
« : Май 06, 2010, 22:24 »

Здравствуйте,

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

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

П.С.
Рассматривал идею сохранить информацию в файле последовательно, и при изменении информации перемещаться в файле в позицию, где произошли изменения и сохранять только изменившиеся байты, но эта идея не совсем подходит. Дело в том, что используеться контейнер QHash, а в нем реализована зависимость типа "Пользователь - Информация". Если добавить/удалить/переименовать  пользователя, то вышеупомянутый файл становиться некорректным, так как перемещение по файлу будет происходить в некорректную позицию.
Записан
Marat(Qt)
Гость
« Ответ #1 : Май 06, 2010, 22:37 »

я бы sqlite использовал для такой задачи.
Записан
JamS007
Гость
« Ответ #2 : Май 06, 2010, 22:42 »

никогда не использовал, можно подробней?
Где можно почитать или посмотреть пример использования?

Другие идеи тоже принимаються...
« Последнее редактирование: Май 06, 2010, 22:45 от JamS007 » Записан
Marat(Qt)
Гость
« Ответ #3 : Май 06, 2010, 23:40 »

Дык, это же базы данных. создаем табличку и пишем в нее. просто для sqlite не нужно сервера, он прямо в программу вклеивается, а данные хранятся в .sql файле, в формате понятном самому sqlite. Просто я думаю если использовать БД, то там явно не производится полная перезапись исходного файла.
С другой стороны стал бы я использовать QHash и ему подобные? Ну пожалуй это сильно от задачи зависит. А вообще я бы запросами ограничился, чтобы и читать данные не все сразу, а только по необходимости. Но, думаю не сложно будет считать всю таблицу в контейнер а записывать в базу(т.е. файл) только то, что нужно, запросами типа update.
Записан
Tonal
Гость
« Ответ #4 : Май 07, 2010, 07:42 »

Замеры проводил насколько тормозит?
Имеет ли смысл это оптимизировать?

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

Но конкретные решения, в любом случае, зависят от общей задачи и критичности данных. Улыбающийся
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #5 : Май 07, 2010, 14:40 »

100К не тот объем который должен тормозить. Можно попробовать писать сначала в память (напр. QBuffer) а потом одним write в файл (его надо держать открытым). Ну и разнообразные игры с числом/частотой сохранений: хранить счетчик несохраненных, проверяться по таймеру и.т.п
Записан
JamS007
Гость
« Ответ #6 : Май 07, 2010, 16:57 »

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

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

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

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

Коллеги, прокоментируйте идею...
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #7 : Май 07, 2010, 17:19 »

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

Коллеги, прокоментируйте идею...
Мне нравится. Др. словами Вы записываете "скрипт" изменений а потом "выполняете" его. Идейно. Операции вставки/удаления тоже должны фиксироваться. Вопрос со скоростью/надежностью все же остается открытым. Файлы надо держать открытыми. Делать flush после каждой записи - накладно. Иначе можно что-то потерять - вероятно лучше с этим примириться, делая flush по таймеру.
Записан
_govorilka
Гость
« Ответ #8 : Май 07, 2010, 20:33 »

+1 про SQLite.

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

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

Хотя, если работать с файлами, можно придумать свою систему баз данных, свой удобный SQL...
Записан
Marat(Qt)
Гость
« Ответ #9 : Май 08, 2010, 10:05 »

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

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

Про PostgreSQL написано тут:
http://www.postgresql.org/docs/8.4/interactive/encryption-options.html

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


Страница сгенерирована за 0.051 секунд. Запросов: 22.