在调试中改进flatbuffer性能的任何方法(c ++ MSVC)

时间:2016-03-18 13:10:44

标签: c++ visual-c++ flatbuffers

我正在尝试在我的公司中使用flatbuffers作为原始结构的替代品。我们需要序列化的类是相当大的,我注意到flatbuffer序列化的开销比运行调试版本时要多。

我使用以下简单的测试程序复制了我的发现(数据类型类似于我们的生产代码中的数据类型):

#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设置为零,但这并没有导致任何显着的性能提升。

2 个答案:

答案 0 :(得分:0)

我注意到您在向量上使用了push_back(),但我没有看到对reserve()的调用。因此,您的代码可能会花费大量时间进行堆分配。我建议您在进入调用vec.reserve(512)的循环之前输入GenerateXYZ()

答案 1 :(得分:0)

再次陷入同样的​​问题并决定使用编译器设置来查看哪些具有最大的效果。万一其他人偶然发现这篇文章,这就是我发现的:

开始使用与问题类似的示例应用程序。运行时间约为40秒。

  • 为任何合适的功能(/ Ob2)启用内联功能:12.5秒
  • 没有'编辑&amp;继续'在pdb(/ Zi):7.6秒
  • 省略基本运行时检查:4.5秒
  • 禁用迭代器调试(_HAS_ITERATOR_DEBUGGING = 0):2.2秒
  • 禁用最小重建(/ Gm-):1.6s秒
  • 启用速度优化(/ O2):400毫秒

当然,这实际上将配置转换为标准版本配置,但是我们能够使用这些选项的子集来实现平缓缓冲性能,使其不再是我们应用程序中的瓶颈。