Лучший формат хранения данных с точки зрения веса и производительности (например, Txt, Asc, Bin и т. Д.)? - PullRequest
3 голосов
/ 13 марта 2012

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

Я использую ASCII, текстовый и двоичный формат.И скажем, для одинакового размера матрицы (например, 10000x10000x200) и точности чисел (например, 5 значащих цифр) я обнаружил, что бинарный формат дает лучшие результаты в целом, затем ASCII и текст с точки зрения скорости доступа / записи и веса в целом(Я не проводил никакого реального тестирования).

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

PS.Я могу использовать C, C ++ или Matlab (не важно, какой из них для меня), если можно помочь достичь лучших результатов.

Ответы [ 3 ]

3 голосов
/ 13 марта 2012

Двоичный код будет намного быстрее в целом. Если вы используете числа с плавающей запятой, вы используете 4 байта на число вместо 1 байта на символ числа - поэтому число 5.34182 составляет 4 байта вместо 7 байтов плюс разделитель.

Пойдя дальше, вы, вероятно, можете сделать лучше. Ваш диск не читает данные побайтно, скорее он читает данные в блоках , и, как правило, вы хотите избежать чтения большего количества блоков, чем нужно. Реальная причина того, что двоичный формат быстрее, заключается не в том, что он занимает меньше байтов, а в том, что он занимает меньше блоков (продукт, состоящий из меньшего количества байтов). Это означает, что вы хотите минимизировать размер диска, поскольку чтение с диска на порядок медленнее, чем чтение из ОЗУ - доступ к диску измеряется в миллисекундах, а доступ к ОЗУ - в микросекундах.

Так что теперь вы можете сделать? Если ваша матрица разреженная , вы можете хранить только ненулевые элементы, что сэкономит вам много места. Поэтому вместо сохранения каждой точки сохраняйте пару (индекс, значение) для каждой записи. Это означает, что каждая запись теперь имеет 8 байтов вместо 4, но если больше половины матрицы равно нулю, вы экономите много места.

Наконец, сжатие может сильно помочь здесь. Конечно, большее сжатие означает больше процессорного времени для распаковки матрицы, но это также может означать более быстрое чтение с диска. Здесь вам действительно нужно экспериментировать - на простом конце спектра Run Length Encoding прост в реализации и часто работает на удивление хорошо. Это работает, потому что если вы храните для маленьких целых чисел и «простых» чисел с плавающей запятой, большинство байтов равны нулю. Это также хорошо работает, если одно и то же число повторяется несколько раз, что происходит в матрицах. Я также рекомендовал бы проверить более продвинутые схемы, такие как bzip2 , которые, хотя и более сложны в вычислительном отношении, могут значительно уменьшить размер диска. Увы, сжатие имеет тенденцию быть очень специфичным для домена, поэтому вы должны экспериментировать здесь. То, что работает в одном домене, не всегда работает в другом.

1 голос
/ 13 марта 2012

Сложный вопрос. И многие люди были там с точки зрения эффективности смешивания библиотек с простотой использования и обмена - вы рассматривали такие вещи, как hdf5 или NetCDF ? У обоих из них есть библиотеки для доступа к C / C ++, а также привязки к общим инструментам, таким как Matlab, Python, R, ...

Тем не менее, в прошлом я тоже писал разовые бинарные заставки.

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

Да, 64 МБ дискового кеша не сильно помогут в моем случае.

К сожалению, я работаю с очень плотными матрицами (конечные элементы с сильными привязками), и двоичный файл с ограниченной точностью, кажется, дает лучшую производительность с точки зрения скорости чтения / записи и размера файлов (намного меньше) без возможности сжатия.

Текстовый формат приводил к гораздо большему размеру файлов по сравнению с Binary, однако после сжатия полученный размер файлов был таким же, как Binary, но требовал значительного времени сжатия. Время чтения / записи также чрезвычайно выше.

Для 3000x3000 (один): время чтения / записи двоичного файла (68 МБ) составило: 0,05 / 0,23 с и 13,8 / 6,5 с для текста (145 МБ). Для 6000x6000 (одиночный): время чтения / записи двоичного файла (274 МБ) составило: 0,22 / 0,92 с и 56/26 с для текста (583 МБ). Однако эти значения могут быть неточными, так как жесткий диск может быть важным ограничивающим фактором для меня.

Тесты проводились с использованием одинаковой точности (разных комбинаций), одинакового размера матрицы (3000x3000, 6000x6000, 12000x12000) и одинакового сродства ЦП и с использованием стандартного Matlab Fwrite , Fprintf , Fread и Fscanf. Я не смог получить более высокий размер / точность, так как скорость чтения / записи жесткого диска была ограничена, а процессор на границе.

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