1

我正在尝试在我的公司中使用 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 设置为零,但这并没有带来任何显着的性能提升。

4

2 回答 2

0

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

于 2016-03-18T13:16:41.107 回答
0

再次遇到同样的问题并决定使用编译器设置来查看哪些具有最剧烈的影响。以防其他人偶然发现这篇文章,这就是我发现的:

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

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

当然,这实际上将配置转换为标准发布配置,但我们能够使用这些选项的一个子集来获得 flatbuffer 性能,使其不再是我们应用程序的瓶颈。

于 2017-11-27T07:47:39.290 回答