简体   繁体   中英

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?

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

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM