Я пытаюсь выбрать простой, но эффективный подход к сериализации для некоторых больших структур данных и надеюсь получить отзывы о простых тестах, которые я только что написал, чтобы помочь мне принять решение.
Рассматриваемая структура данных содержит несколько двумерных векторов с плавающей точкой:
vector<<vector float> > data;
Векторы компонентов в основном имеют одинаковый размер, но это не гарантия. Однако существует очень ограниченное количество вариаций в размерах компонентных векторов. Например, обычно 99% компонентных векторов будут одинакового размера, а остаток будет несколько кратным базовому размеру. Может быть возможно обрезать более длинные или дополнить более короткие векторы компонентов, но это может оказать негативное влияние на производительность программы в некоторых случаях.
Эти двумерные векторы обычно содержат несколько сотен тысяч компонентных векторов, тогда как каждый компонентный вектор обычно содержит 40 элементов.
Эти данные считываются один раз при первой загрузке программы, и после этого информация многократно повторяется, но никогда не изменяется.
С точки зрения того, как сериализовать эти данные, кажется, есть два очень очевидных варианта:
- Преобразование двумерных векторов в одномерные и сериализацию одномерных векторов с помощью простого заголовка. Это должно быть очень быстрым для чтения и записи и примерно таким же, как двумерный вектор для итерации, хотя и с немного другой настройкой. К сожалению, это происходит в случае, когда векторы компонентов имеют переменную длину; итерация также потребует дополнительного учета.
- Сохраните 2-ую структуру и используйте немного более сложный заголовок. Это, вероятно, будет несколько медленнее читать и писать, но мы все равно делаем это только один раз. Это позволяет нам учитывать векторы компонентов переменной длины и не требует дополнительного учета в ходе итерации. Существующий код, использующий эти данные, изменять не нужно.
Я написал простую тестовую программу, чтобы попытаться получить общее представление о том, как эти варианты могут быть реализованы на практике:
run-serializer.cpp: http://pastebin.com/AzWivQDU
Serializer.h: http://pastebin.com/dvbqN1EY
Serializer.cpp: http://pastebin.com/0eDCg7sE
$ g++ -o run-serializer run-serializer.cpp Serializer.cpp
$ ./run-serializer 500
Initializing tests...
Total elems: 11441408
Test binfile: test.bin
Binary write: 0.038397
Average runtimes for 500 iterations:
Binary 1d read: 0.0228143
Binary 2d read: 0.156756
1d iter time: 0.125914
2d iter time: 0.126896
Похоже, это указывает на то, что на моем ноутбуке и в моем примере реализации 2d версия занимает примерно в 8 раз больше, чем 1d версия. Не слишком удивительно, и для моих целей это разумное количество времени. Это также указывает на то, что, как и ожидалось, разница между временем 1d и временем 2d очень мала, но, возможно, версия 1d выигрывает smidgen.
Учитывая (потенциально) переменную длину векторов компонентов, я склонен придерживаться существующего двумерного подхода. Начальный процесс загрузки заметно медленнее, но все же довольно незначителен с точки зрения приложения. Похоже, итерация в любом случае не является проблемой, и двумерный подход означает, что мне не придется изменять любой другой код, использующий в настоящее время эти структуры данных.
Так что, я думаю, мой настоящий вопрос:
- Являются ли эти тесты в целом разумными, и имеют ли смысл сделанные из них выводы?
Извиняюсь за скучность.