0

I want to ask a question about vectors in C++. I am learning about vectors at the moment, so I want to ask about it.

Is this code more efficient

vector<int> numbers;
numbers.reserve(10);
for (int i = 0; i < 10; i++){
   numbers.push_back(i + 1);
}

than this

vector<int> numbers;
for (int i = 0; i < 10; i++){
   numbers.push_back(i + 1);
}

?

Justas
  • 1
  • 3
  • Since in the first scenario you already declared the size of the vector, it makes more sense if you are aware of the size of the vector. In the second case If you `push_back` another element, then a full vector will typically allocate double the memory it's currently using - since allocate + copy is expensive. – peerpressure Feb 12 '22 at 16:43

2 Answers2

2

Yes. Although for '10' you will not notice a difference.

reserve will immediately reserve memory on the heap for the amount of elements you specify.

Without reserve, vector will start with a "reasonable" value. Whenever it needs more space to put elements in, it will reallocate and reassign all elements. This takes time, so not having to do this is faster.

But: don't go adding reserve to all your code.

  • It clutters your code.
  • You can get it wrong, like, reserving 10, but requiring 11.

My advice would be to use reserve, only after you have determined that reallocation causes performance issues.

Hajo Kirchhoff
  • 1,969
  • 8
  • 17
0

Yes. Or at least it won't be slower. If you reserve some space for a vector, it won't have to move every time it reaches its capacity. Though if you didn't know, you can just provide size in vector's constructor like that:

vector<int> numbers(10);
for (int i = 0; i < 10; i++) 
    numbers[i] = i + 1;

and it's even better than reserving memory (it's not slower and can help in some cases). Also, a nice way of doing this might be using stl's function iota (#include <numeric>):

vector<int> numbers(10);
iota(numbers.begin(), numbers.end(), 1);
Hubizon
  • 1
  • 2
  • you might want to justify `even better than reserving memory`. Why is it better? It does more work as it will initialise all of the members, those values are then initialised again in the for loop. – Alan Birtles Feb 12 '22 at 16:55
  • @AlanBirtles Well you have a point there, but it doesn't really take that much time. You can check out [this answer](https://stackoverflow.com/a/53892023/18189233), it's even faster than just reserving memory. It's because `push_back()` takes more time than `operator[]`. You can also use functions like `iota` or structure binding (`for (auto& v : V)`) that way, or initialize every member of the vector easily just by passing a second argument. Also, I think it looks more neat, is more flexible and easier to use. Although in some specific situation, it's better to use `reserve`. – Hubizon Feb 12 '22 at 17:27
  • looks like those benchmarks were with unoptimised code? Turning on optimisations removes the difference. For more complex types there will probably be more of a difference. Either way you should edit your answer to change "better" into something more specific – Alan Birtles Feb 12 '22 at 17:56