Как использовать оптимизацию массива в ускоренной сериализации

Я должен сериализовать объект, который содержит 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 технически непереносимым.

Другие вопросы по тегам