Как ускорить десериализацию boost :: сериализации? - PullRequest
7 голосов
/ 24 июня 2011

Я использую boost :: serialization для сохранения объекта, который содержит эти данные:

struct Container
{
    struct SmallObject
    {
        struct CustomData
        {
            unsigned first;
            float second;
        };

        std::vector<CustomData> customData; // <- i can have 1 to 4 of these in the std::vector
        float data1[3];
        float data2[3];
        float data3[2];
        float data4[4];
    };

    std::vector<SmallObject> mySmallerObjects;  // <- i can have 8000 to 13000 of the std::vector
};

Код сериализации выглядит следующим образом (в навязчивой версии я не писал декларации функций выше для удобства чтения):

template<class Archive> void Container::SmallObject::CustomData::serialize(Archive& ar, unsigned /*version*/)
{
    ar & first;
    ar & second;
}

template<class Archive> void Container::SmallObject::serialize(Archive& ar, unsigned /*version*/)
{
    ar & customData;
    ar & data1
    ar & data2;
    ar & data3;
    ar & data4;
}

template<class Archive> void Container::serialize(Archive& ar, unsigned /*version*/)
{
    ar & mySmallerObjects;
}

Я использую двоичные_архивы. В режиме выпуска загрузка моего контейнера (с 12000 маленьких объектов) занимает около 400 миллисекунд. Мне сказали, что это слишком долго. Существуют ли какие-либо настройки или другие схемы памяти, которые могли бы ускорить процесс загрузки? Должен ли я отказаться от использования boost :: serialization?

Ответы [ 2 ]

3 голосов
/ 24 июня 2011

Если бы мне пришлось выбрать самый большой недостаток Boost.Serialization, это было бы плохой производительностью.Если 400 мс действительно слишком медленные, либо получите более быстрое оборудование, либо переключитесь на другую библиотеку сериализации.

Тем не менее, на случай, если вы делаете что-то явно «неправильное», вы должны опубликовать код сериализации для * 1003.*, Container::SmallObject и Container::SmallObject::CustomData.Вы также должны убедиться, что на самом деле десериализация занимает 400 мс, а не комбинацию десериализации + чтения данных с диска;то есть загрузить данные в какой-то поток памяти и десериализовать их, а не десериализовать из std::fstream.


EDIT (в ответ на комментарии):

Этот код работает для меня, используя VC ++ 2010 SP1 и Boost 1.47 beta:

double loadArchive(std::string const& archiveFileName, Container& data)
{
    std::ifstream fileStream(
        archiveFileName.c_str(),
        std::ios_base::binary | std::ios_base::in
    );
    std::stringstream buf(
        std::ios_base::binary | std::ios_base::in | std::ios_base::out
    );
    buf << fileStream.rdbuf();
    fileStream.close();

    StartCounter();
    boost::archive::binary_iarchive(buf) >> data;
    return GetCounter();
}

Если это не работает для вас, он должен быть привязан к компилятору и / или версииBoost, который вы используете (что к чему?).

На моем компьютере для сборки выпуска x86 (с включенной генерацией кода времени соединения) загрузка данных с диска составляет ~ 9% от общего временивзятый для десериализации файла размером 1,28 МБ (1 Container, содержащий 13000 SmallObject экземпляров, каждый из которых содержит 4 CustomData экземпляров);для сборки выпуска x64 загрузка данных с диска составляет ~ 17% от общего времени, необходимого для десериализации файла размером 1,53 МБ (столько же объектов).

1 голос
/ 24 июня 2011

Я бы предложил записать количество элементов в поток сериализации и затем использовать std :: vector :: reserve для выделения всей необходимой вам памяти. Таким образом, вы будете выполнять минимальное количество выделений.

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