Как использовать оптимизацию массива в ускоренной сериализации
Я должен сериализовать объект, который содержит std::vector, который может содержать тысячи членов, с такими размерами вектора сериализация не масштабируется хорошо.
Согласно документации, Boost предоставляет массив классов-оболочек, который обертывает вектор для оптимизации, но генерирует тот же xml-вывод. Погружаясь в буст-коде, я нашел класс с именем use_array_optimization, который, кажется, управляет оптимизацией, но каким-то образом деактивирован по умолчанию. Я также пытался переопределить функцию сериализации без результатов.
Я хотел бы знать, как активировать эту оптимизацию, так как документы на повышение неясны.
заранее спасибо
3 ответа
Наконец, я использовал макрос BOOST_SERIALIZATION_SPLIT_MEMBER() и написал две функции для загрузки и сохранения. Функция Save выглядит следующим образом:
template<class Archive>
void save(Archive & ar, const unsigned int version) const
{
using boost::serialization::make_nvp;
std::string sdata;
Vector2String(vData, sdata);
ar & boost::serialization::make_nvp("vData", sdata);
}
Функция Vector2String просто берет данные в векторе и форматирует их в std::string. Функция загрузки использует функцию, которая изменяет кодировку.
Идея оптимизации массива заключается в том, что для массивов типов, которые могут быть заархивированы путем простого "выгрузки" их представления в архив как есть, "выгрузка" всего массива сразу происходит быстрее, чем "выгрузка" одного элемента за другим,
Из вашего вопроса я понимаю, что вы используете XML-архив. Оптимизация массива в этом случае не применяется, потому что сериализация элементов в любом случае подразумевает преобразование.
У вас есть несколько способов сериализовать
vector
с ускоренной сериализацией в XML. Из того, что я прочитал в комментариях, вы ищете случай 2 ниже.
Я думаю, вы не можете изменить, как
std::vector
сериализуется библиотекой после включения
boost/serialization/vector.hpp
, однако вы можете заменить там код на свой и на что-то близкое к случаю 2.
0. Библиотека по умолчанию, не оптимизирована
Во-первых, использовать значение по умолчанию, заданное библиотекой, которое, насколько мне известно, ничего не оптимизирует:
#include <boost/serialization/vector.hpp>
...
std::vector<double> vec(4);
std::iota(begin(vec), end(vec), 0);
std::ofstream ofs{"default.xml", boost::archive::no_header};
boost::archive::xml_oarchive xoa{ofs};
xoa<< BOOST_NVP(vec);
выход:
<vec>
<count>4</count>
<item_version>0</item_version>
<item>0.00000000000000000e+00</item>
<item>1.00000000000000000e+00</item>
<item>2.00000000000000000e+00</item>
<item>3.00000000000000000e+00</item>
</vec>
1. Вручную используйте, чтобы данные были непрерывными
#include <boost/serialization/array_wrapper.hpp> // for make_array
...
std::ofstream ofs{"array.xml"};
boost::archive::xml_oarchive xoa{ofs, boost::archive::no_header};
auto const size = vec.size();
xoa<< BOOST_NVP(size) << boost::serialization::make_nvp("data", boost::serialization::make_array(vec.data(), vec.size()));
выход:
<size>4</size>
<data>
<item>0.00000000000000000e+00</item>
<item>1.00000000000000000e+00</item>
<item>2.00000000000000000e+00</item>
<item>3.00000000000000000e+00</item>
</data>
2. Вручную используйте эти данные как двоичные и непрерывные.
#include <boost/serialization/binary_object.hpp>
...
std::ofstream ofs{"binary.xml"};
boost::archive::xml_oarchive xoa{ofs, boost::archive::no_header};
auto const size = vec.size();
xoa<< BOOST_NVP(size) << boost::serialization::make_nvp("binary_data", boost::serialization::make_binary_object(vec.data(), vec.size()*sizeof(double)));
<size>4</size>
<binary_data>
AAAAAAAAAAAAAAAAAADwPwAAAAAAAABAAAAAAAAACEA=
</binary_data>
Я думаю, что это делает XML технически непереносимым.