Каков наилучший способ для бинаризации данных - PullRequest
2 голосов
/ 16 марта 2011

У меня есть несколько файлов данных, которые записываются как tag = value, где tag - это строка, а value может быть числовым, строка, массив и т. Д. Я использую этот формат, потому что он читабелен и его легко редактировать. Теперь у каждого класса, который создается с использованием этого формата, есть метод load, который читает нужные теги и использует значения, найденные в этих тегах. Я хочу сделать двоичные данные для увеличения скорости загрузки. Одним из способов было бы использование метода ToBinary (имя не имеет значения) в каждом классе, который считывает старые данные и записывает их в файл, а новый файл используется для создания экземпляра объекта. Это можно сделать в автономном режиме, только один раз / приложение. У вас есть другие предложения для этого? Я использую C ++ для этого.

Edit: Я думаю, что самая дорогая часть сейчас - это анализ файла, когда я впервые его читаю, и после этого поиск нужного мне тега, а не чтение файла с диска. Я могу использовать пользовательскую файловую систему, чтобы иметь несколько маленьких файлов в одном большом файле.

Ответы [ 6 ]

1 голос
/ 16 марта 2011

Для этого у меня есть базовый класс сериализации с функциями To / From с небольшим заголовком, в который может быть встроена обработка версий. Я думаю, что это хорошая система для более простых данных, которые должны храниться локально и в большинстве случаев «только для чтения».

Примерно так:

class SeralizeMe
{
public:

 virtual bool To(Archive &file)=0;
 virtual bool From(Archive &file)=0;

 virtual bool NeedsSave(void)=0;

};

Однако не используйте эту систему, если вы:

  • Необходимо часто менять формат.
  • Необходимо выбрать, какие данные загружать и что хранить.
  • Используйте большие файлы, которые особенно чувствительны к перебоям питания при сохранении.

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

1 голос
/ 16 марта 2011

Если вы используете файл, то использование двоичных данных, вероятно, существенно не улучшит вашу производительность, если только у вас нет очень большого куска данных для хранения в файле (изображения, видео ...).

Но в любом случае вы можете использовать двоичный алгоритм сериализации, такой как алгоритм из Boost .

1 голос
/ 16 марта 2011

Я раньше этим не пользовался, но уверен, Модуль сериализации Boost - хорошее место для начала.

0 голосов
/ 16 марта 2011

У меня есть две идеи для вас:

1) Если список тегов постоянен и известен заранее, вы можете преобразовать каждый из них в BYTE (или WORD), после чего следует длина значения (в байтах), за которой следует необработанная c-строка полезной нагрузки значения.

Например, с учетом следующего:

Tag1 = "hello World!" // 12 bytes in length (achieved by "strlen(value) * sizeof(char)" )
Tag2 = "hello canada!"  // 13 bytes in length 

Вы можете превратить это в поток байтов:

0x0001 0x000B // followed by 12 bytes representing the 'value' // 0x0002 0x000C // followed by 13 bytes representing 'value2'

Ваша программа просто должна знать, что заголовок WORD "0x0001" представляет Tag1, а заголовок "0x0002" представляет Tag2.

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

2) Возможно, медленный бит - это просто ваша реализация парсинга текста? Подумайте об использовании специальной библиотеки с открытым исходным кодом для того, что вы пытаетесь сделать. Пример: " boost :: property_tree "

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

0 голосов
/ 16 марта 2011

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

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

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

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

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

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

Преобразовать поле ключа для использования чисел, a.k.a. tokens . Поскольку токены являются числовыми, они могут использоваться как индексы в таблицах переходов (также для переключения операторов) или просто как индексы в массивах.

В крайнем случае конвертируйте файл в двоичный файл. Двоичная версия должна иметь два поля: ключ как токен и значение. Перенос данных большими кусками в память.

Основная информация

  1. Перенос больших блоков данных в память.
  2. Профиль перед внесением изменений в установить базовую производительность измерение.
  3. Оптимизация по одному шагу за раз, профилирование после каждой оптимизации.
  4. Предпочитают хранить файл данных на человеке читаемая форма.
  5. Минимизировать изменения в файле данных.
  6. Конвертировать файл в фиксированную длину поля.
  7. Попробуйте использовать темы или многозадачность поэтому приложение не ждет.
  8. Преобразование текста в числовые токены (уменьшает читабельность)
  9. Конвертировать данные в двоичный файл как последний курорт (очень трудно для людей чтение и отладка).
0 голосов
/ 16 марта 2011

Еще один протобуф от Google. Не самый быстрый, но он может поддерживать эволюционирующие типы данных, он очень эффективен в сети и поддерживает другие языки.

Ссылка здесь .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...