1

Is there a performance reason why a vector would be initialized with size?

For example vector<myClass> v(10); as opposed to vector<myClass> v and push_back as needed?

gsamaras
  • 71,951
  • 46
  • 188
  • 305
  • After each push back, print out `capacity()`. Whenever it changes, a dynamic allocation has occurred. Now try by calling `reserve` first. – Neil Kirk Apr 01 '15 at 00:32

2 Answers2

3

vector<myClass> v(10) pre-allocates the internal array once time and auto-fills it with 10 default-constructed myClass objects.

vector<myClass> v does not pre-allocate the array, but you can use reserve() and resize() for that.

push_back() will re-allocate and copy the internal array each time that the new size() would exceed the current capacity().

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
2

If the push_back() grows the vector past its current capacity(), it will reallocate its array, something that is not efficient.

So, if you tell the vector exactly how many elements you are going to store, then you do not pay the cost of re-allocating the vector, especially if the vector has to change location in the memory (because it does not fit where it is), thus it copies itself (additional cost!).

Reallocation of a vector.

Resize.


But should you believe me? Maybe. You should however believe the facts:

Test code

#include <vector>
#include <iostream>
#include <ctime>
#include <ratio>
#include <chrono>

using namespace std;

int main() {
  const int N = 1000000;

  using namespace std::chrono;
  {

  // push_back only

  high_resolution_clock::time_point t1 = high_resolution_clock::now();
  vector<int> v1;
  for(int i = 0; i < N; ++i)
    v1.push_back(i);
  high_resolution_clock::time_point t2 = high_resolution_clock::now();

  duration<double> time_span = duration_cast<duration<double>>(t2 - t1);

  std::cout << "It took me " << time_span.count() << " seconds.";
  std::cout << std::endl;
  }

  {
  // set size and use operator []

  high_resolution_clock::time_point t1 = high_resolution_clock::now();
  vector<int> v2(N);
  for(int i = 0; i < N; ++i)
    v2[i] = i;
  high_resolution_clock::time_point t2 = high_resolution_clock::now();

  duration<double> time_span = duration_cast<duration<double>>(t2 - t1);

  std::cout << "It took me " << time_span.count() << " seconds.";
  std::cout << std::endl;
  }
  return 0;
}

Output

It took me 0.0170491 seconds.
It took me 0.00236058 seconds.

As you can see, the experimental results show that by setting the size of the vector, we are faster by one magnitude.

My source for time measurements.

Community
  • 1
  • 1
gsamaras
  • 71,951
  • 46
  • 188
  • 305
  • Can you clarify what you mean by too big. If I do successive push_back(s) , at what point is the vector deemed too big ? – Govinda Keshavdas Apr 01 '15 at 00:33
  • 2
    It reallocates the internal array when the new `size()` would exceed the current `capacity()`. You can use `reserve()` to set the `capacity()`, and `resize()` to set the `size()`. – Remy Lebeau Apr 01 '15 at 00:33
  • See my edit. By too big, I mean bigger than what the vector can store at the time. Exactly what @RemyLebeau said! – gsamaras Apr 01 '15 at 00:34
  • @G.Samaras: gee, thanks (not) for copying *my* comment into *your* answer :-p – Remy Lebeau Apr 01 '15 at 00:36