6

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?

1
  • Side note: C++ doesn't specify the order of parameter evaluation, so your 3 v++ expressions could be evaluated in any order at the whim of the optimizer, leading to hard-to-trace down bugs after a future code change or compiler upgrade. Commented Jul 26, 2017 at 14:56

2 Answers 2

9

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)); 
Sign up to request clarification or add additional context in comments.

1 Comment

For a vector, front_inserter is slow, since for each insertion, it has to bump back all other elements in the vector.
4

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

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.