【问题标题】:What is the most efficient way to get all elements from a ProtoBuf RepeatedField?从 ProtoBuf 重复字段中获取所有元素的最有效方法是什么?
【发布时间】:2012-09-20 09:35:07
【问题描述】:

我已使用 Google 的 Protcol 缓冲区将一组浮点数序列化为 RepeatedField

在反序列化数据时,我使用另一个设置类以更适合我的游戏类的形式保存信息。静态CreateFrom 方法提取和转换数据。

class VoxelTerrainSettings
{
public:
    std::vector<int> indices;
    btAlignedObjectArray<btVector3> vertices;

    VoxelTerrainSettings(void);
    ~VoxelTerrainSettings(void);

    static VoxelTerrainSettings CreateFrom(const VoxelTerrainProtoBuf::VoxelTerrainSettings &settings)
    {
        VoxelTerrainSettings s;

        int numIndices = settings.indices().size();

        s.indices.reserve(numIndices);

        for (int i = 0; i < numIndices; ++i)
        {
            s.indices.push_back(settings.indices().Get(i));
        }

        int numVertices = settings.vertices().size();

        s.vertices.reserve(numVertices);

        int v = 0;

        for (int i = 0; i < numVertices; ++i)
        {
            s.vertices.push_back(btVector3(settings.vertices().Get(v++), settings.vertices().Get(v++), settings.vertices().Get(v++)));
        }

        return s;
    }

    //VoxelTerrain Load();
};

但是,当前从 RepeatedField 中提取所有元素的方法似乎不是很优雅。

我尝试采用更有效的方法,但它们都抛出了超出范围的错误。

std::copy(settings.vertices().begin(), settings.vertices().end(), vv.begin());
std::copy(&settings.vertices().Get(0), &settings.vertices().Get(settings.vertices().size() - 1), &vv[0]);

我可以使用哪些方法来提高元素提取效率?

【问题讨论】:

  • 旁注:C++ 没有指定参数评估的顺序,因此您的 3 个 v++ 表达式可以按照优化器的任意顺序进行评估,导致难以追踪未来代码更改或编译器升级后的错误。

标签: c++ arrays protocol-buffers


【解决方案1】:

std::copy 使用 std::front_inserter/std::back_inserter 迭代器类型将值插入容器 请尝试以下操作:

// inserting into list/deque
std::copy(settings.vertices().begin(), settings.vertices().end(), std::front_inserter(vv));
// inserting into vector
std::copy(settings.vertices().begin(), settings.vertices().end(), std::back_inserter(vv)); 

【讨论】:

  • 对于向量,front_inserter 很慢,因为对于每次插入,它都必须退回向量中的所有其他元素。
【解决方案2】:

最快的是先预留空间,然后循环转化为optimize caching

s.indices.reserve(settings.indices().size());
s.vertices.reserve(settings.vertices().size());

for (auto& vertex : settings.vertices()) {
   s.indicies.push_back(...);
   s.verticies.push_back(...);
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-10
    • 2013-04-07
    • 1970-01-01
    • 2010-10-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多