Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the most efficient way to get all elements from a ProtoBuf RepeatedField?

I have serialized an array of floats into a RepeatedField using Google's Protcol Buffers.

When deserializing the data I use another settings class to hold the information in a more appropriate form for my game classes. A static CreateFrom method extracts and converts the data.

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();
};

However, the current method for extracting all the elements from the RepeatedField doesn't seem very elegant.

I've tried adopting a more efficient approach but they both throw out of range errors.

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]);

What methods could I use to make element extraction more efficient?

like image 539
user1423893 Avatar asked Sep 28 '12 13:09

user1423893


People also ask

What is repeated in Protobuf?

repeated : this field can be repeated any number of times (including zero) in a well-formed message. The order of the repeated values will be preserved.

Does order matter in Protobuf?

The textual order is largely irrelevant, although it may impact some code generation tooling - but most languages don't care about declaration order, so even that: won't matter.

What is Protobuf C++?

Protocol Buffers (Protobuf) is a free and open-source cross-platform data format used to serialize structured data. It is useful in developing programs to communicate with each other over a network or for storing data.


2 Answers

std::copy uses std::front_inserter/std::back_inserter iterator types for inserting values into containers Try the following:

// 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)); 
like image 164
DarkWanderer Avatar answered Oct 29 '22 11:10

DarkWanderer


Fastest is to reserve space up front, and then transform in one loop to 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(...);
}
like image 43
Edward Brey Avatar answered Oct 29 '22 10:10

Edward Brey