visual Любой способ улучшить производительность flatbuffer при отладке (c ++ MSVC)

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

Я повторил свои выводы с помощью следующей простой тестовой программы (тип данных аналогичен типу данных в нашем производственном коде):

#include "stdafx.h"#include <flatbuffers/flatbuffers.h>
#include "footprints_generated.h"#include <vector>
#include <iostream>
#include <chrono>

using namespace Serialization::Dummy::FakeFootprints;

flatbuffers::FlatBufferBuilder builder;

flatbuffers::Offset<XYZData> GenerateXYZ()
{
return CreateXYZData(builder,
1.0,
2.0,
3.0,
4.0,
5.0,
6.0,
7.0,
8.0,
9.0,
10.0,
11.0,
12.0,
13.0,
14.0,
15.0,
16.0,
17.0,
18.0,
19.0,
20.0);
}

flatbuffers::Offset<Fake> GenerateFake()
{
std::vector<flatbuffers::Offset<XYZData>> vec;
for(int i = 0; i < 512; i++)
{
vec.push_back(GenerateXYZ());
}

auto XYZVector = builder.CreateVector(vec);

return CreateFake(builder,
1.0,
2.0,
3.0,
4.0,
5.0,
6.0,
7.0,
8.0,
9.0,
10.0,
XYZVector);
}

int main()
{
auto start = std::chrono::steady_clock::now();

for(auto i = 0; i < 1000; i++)
{
auto fake = GenerateFake();
}

auto end = std::chrono::steady_clock::now();
auto diff = end - start;
std::cout << std::chrono::duration <double, std::milli>(diff).count() << " ms" << std::endl;

std::string dummy;
std::cin >> dummy;
}

Что занимает около 40 секунд для запуска на моем компьютере в режиме отладки (около 400 мс в выпуске).
Я ищу любой способ улучшить производительность в отладочной сборке. Профилирование показало, что большая часть времени тратится на код std :: vector, поэтому я попытался установить нулевое значение _ITERATOR_DEBUG_LEVEL, но это не привело к значительному увеличению производительности.

1

Решение

Я заметил, что вы используете push_back() на векторе, но я не вижу вызова reserve(), Поэтому ваш код, вероятно, тратит много времени на выделение кучи. Я бы предложил вам положить в vec.reserve(512) прежде чем войти в цикл, который вызывает GenerateXYZ(),

0

Другие решения

Снова столкнулся с той же проблемой и решил поиграть с настройками компилятора, чтобы увидеть, какие из них имеют наиболее радикальный эффект. На случай, если кто-нибудь еще наткнется на этот пост, вот что я нашел:

Начал с примера приложения, похожего на вопрос. Время выполнения составило примерно 40 секунд.

  • Включение встроенной функции для любой подходящей функции (/ Ob2): 12,5 секунд
  • Нет редактировать & продолжить ‘в pdb (/ Zi): 7,6 секунд
  • Пропустить базовые проверки во время выполнения: 4,5 секунды
  • Отключить отладку итератора (_HAS_ITERATOR_DEBUGGING = 0): 2,2 секунды
  • Отключить минимальное перестроение (/ Gm-): 1,6 секунды
  • Включить оптимизацию по скорости (/ O2): 400 миллисекунд

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

0

По вопросам рекламы [email protected]