Повысить оптимизацию десериализации? - PullRequest
0 голосов
/ 11 апреля 2009

Я десериализирую изрядное количество данных с помощью Boost.Serialization (по одному на каждый кадр). Однако, когда я выводлю, сколько времени занимает десериализация, она сильно меняется. На данный момент он не слишком медленный, но было бы неплохо сделать это быстрее. Данные представляют те же классы, массивы, карты и векторы, но просто с разными значениями.

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

Вот несколько примеров чтения в качестве примера:

Deserialization - 390 milliseconds
Deserialization - 422 milliseconds
Deserialization - 422 milliseconds
Deserialization - 422 milliseconds
Deserialization - 438 milliseconds
Deserialization - 2156 milliseconds
Deserialization - 1797 milliseconds
Deserialization - 1656 milliseconds
Deserialization - 1328 milliseconds
Deserialization - 1219 milliseconds
Deserialization - 1078 milliseconds
Deserialization - 1078 milliseconds

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

Обновление: я понял, что небольшая проблема с флагами оптимизации, которые я использовал, приводила к неправильной записи данных сериализации, что приводило к несогласованности времени десериализации. После исправления это теперь постоянно составляет 750 - 780 миллисекунд в каждом кадре.

Тем не менее, мой первоначальный вопрос остается в силе, так как в настоящее время я сериализую и десериализирую весь контейнер stl, когда я действительно хочу только сериализовать содержимое (так как размер и индексирование контейнера останутся точно такими же). Я не уверен, что лучший способ сделать это все же.

Ответы [ 4 ]

3 голосов
/ 16 апреля 2009

Возможно, вы захотите пересмотреть дизайн функции, используя эту сериализацию.

Из вашего описания кажется, что вы очень часто сериализуете / десериализуете весь контейнер STL. Это не должно быть обязательным. Сериализация не должна использоваться, если только данные не должны быть сохранены, чтобы их можно было восстановить позже или кем-то еще.

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

1 голос
/ 17 апреля 2009

Повышенная сериализация предоставляет шаблонные методы сохранения для коллекций STL, например, за комплект:

template<class Archive, class Key, class Compare, class Allocator >
inline void save(
    Archive & ar,
    const std::set<Key, Compare, Allocator> &t,
    const unsigned int /* file_version */
){
    boost::serialization::stl::save_collection<
        Archive, std::set<Key, Compare, Allocator> 
    >(ar, t);
}

, которые просто делегируют save_collection. Я предполагаю, что вы могли бы определить специализацию для своего типа коллекции, которая выполняет сериализацию по вашему выбору, например ::

namespace boost {
namespace serialization {

template<class Archive>
inline void save<MyKey, MyCompare, MyAlloc> (
    Archive & ar,
    const std::set<MyKey, MyCompare, MyAlloc> &t,
    const unsigned int /* file_version */
){
    // ...
}

}
}

В качестве отправной точки вы можете взять копию реализации save_collection (из collection_save_imp.hpp) и оптимизировать ее под свои требования. Например. используйте класс, который запоминает размер коллекции из предыдущего вызова и, если он не изменился, повторно используйте тот же буфер.

Вам также может понадобиться специализация для вашего типа участника. В этот момент сомнительно, получаете ли вы какое-либо значение от ускоренной сериализации.

Я знаю, что это немного расплывчато, но трудно быть более конкретным, не зная, какой тип коллекции вы используете, какой тип элемента и т. Д.

1 голос
/ 13 апреля 2009

Отказ от ответственности: я не использую сериализацию наддува.

При этом: стандартная проблема с этими проблемами более или менее описана вами: для любой отдельной сериализации вы запрашиваете несколько (иногда много) кусков памяти у ОС, а затем освобождаете их, когда вы на самом деле более или менее знаю, сколько памяти вам нужно для начала. Единственное известное мне решение состоит в том, чтобы реализовать нечто похожее на «пул» Apache: вы выделяете блок памяти, и ваш распределитель (который вы предоставляете stl или для повышения) работает внутри этого пула; тогда у вас есть классы, такие как Pool :: string, которые выделяют память внутри пула. Два предупреждения:

  • Да, это не очень C ++ ish, но вы можете положить хороший конверт вокруг него (системный архитектор, где я работаю, сделал что-то вроде этого).
  • да, вы должны позаботиться о случае, когда вам нужно выделить другой пул.
0 голосов
/ 16 апреля 2009

Мое первое предложение, поскольку я не вижу вашего кода, - использовать инструмент профилирования для определения фактических узких мест.

Распределение / освобождение памяти вполне может быть основной проблемой, и в этом случае выделение пула - при условии, что у вас есть объекты фиксированного размера - как упоминает Дэвид. скорее всего, поможет.

Если вы сериализуете большой массив объектов в обычный файл формата ASCII, преобразование из ASCII в двоичный файл вполне может занять некоторое нетривиальное время. Эквивалент atoi (), скорее всего, быстрый, но когда вы говорите «frame», я предполагаю некоторый тип изображения или сетевой буфер, и он, вероятно, большой / длинный Таким образом, накладные расходы на atoi () вполне могут быть значительными, если их выполнять миллионы раз.

Я тоже не понимаю разницы, которую вы проводите между содержанием и объектами. В целом, в коллекциях не слишком много накладных расходов с точки зрения пространства, они могут быть и во «времени» в отношении хеширования и перебалансировки дерева, но профилировщик также должен это показать.

Короче говоря, часть, которую вы считаете медленной, вполне может иметь ограниченное влияние на общую производительность. Профиль и убедитесь наверняка.

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