Remi.b Remi.b - 1 month ago 6
C++ Question

How can I avoid extra copying when constructing a vector to be returned?

C++ newbie here! I wrote a code who is considering a

WORLD
which made of a vector of
CITIES
. This world gets updated
nbTimeStep
times. Here is a rough summary of what my code looks like. For ease of reading, all class names are in all caps.

// Definition of Class `WORLD`
class WORLD
{
private:
vector<CITY> cities;
public:
void AddCity(CITY& city)
{
cities.push_back(city);
}
}

// In main

WORLD world(Arguments);
for (int time_step=0 ; time_step < nbTimeSteps ; time_step++)
{
WORLD EmptyWorld;
world = ReCreateWorld(world,EmptyWorld); // The object `EmptyWorld` will be returned after being 'filled' with cities.
}


where the function
ReCreateWorld
is defined as

WORLD& ReCreateWorld(WORLD& OldWorld, WORLD& NewWorld)
{
for (int city_index=0 ; city_index < NbCities ; city_index++)
{
/* Long Process of creating a single 'CITY' called `city`
...
...
*/


// Add the city to the list of cities (process I am trying to optimize)
NewWorld.AddCity(city);
}
return NewWorld;
}


After profiling, I see that about 20% of the time the process is in the method
AddCity
. I never need two instances of any given
CITY
, so it seems silly to lose so much time copying each city. How could I go around this issue?




Some may want to comment on the fact that I pass an empty
WORLD
to
ReCreateCities
as it is not very elegant. I did that mainly to emphasize that the slow copying part happen at the line
cities.push_back(city);
and not when
ReCreateWorld
return its
WORLD
.

Answer

Like Justin and Daniel suggested, use a move c-tor. Old school way is to use pointers, e.g. typedef std::unique_ptr CITY_PTR; std::vector cities; And push only pointers of cities.

You can try something similar to emplace http://www.cplusplus.com/reference/vector/vector/emplace/ which forwards c-tor arguments directly.