1

I want to create a std::vector<int> of a known size and immediately fill it with some generated values. Is there a way to do this without either (1) first zero-filling the vector to the desired size or (2) using reserve then push_back on every element?

For example, to fill the vector with values 0 though size-1:

// method 1
vector<int> fill_resize(int s) {
  vector<int> v(s);
  for (int i = 0; i < s; i++) {
    v[i] = i;
  }
  return v;
}

// method 2
vector<int> fill_push_back(int s) {
  vector<int> v;
  v.reserve(s);
  for (int i = 0; i < s; i++) {
    v.push_back(i);
  }
  return v;
}

Method (1) wastes time by redundantly zero filling, and method (2) needs the machinery of push_back on every insert, which in practice compiles poorly.

Before someone jumps in and says "compilers are smart, they'll optimize this for you!" - check out the generated assembly on cutting edge compilers at -O2. It is pretty awful, with the push_back variant taking the cake in awfulness1.


1Interestingly enough, the awful push_back version still wins for very large vectors, because there you are limited mostly by memory bandwidth, and the zero-then-fill approach of method 1 takes 2x the bandwidth. The push_back approach at least only loops over the values once, but using a slow loop.

BeeOnRope
  • 51,419
  • 13
  • 149
  • 309
  • Comments are not for extended discussion; this conversation has been [moved to chat](http://chat.stackoverflow.com/rooms/138407/discussion-on-question-by-beeonrope-efficiently-populate-vector-of-known-size). – Bhargav Rao Mar 18 '17 at 15:55

1 Answers1

3

You could:

Community
  • 1
  • 1
user673679
  • 1,196
  • 1
  • 16
  • 32
  • Thanks. I especially like the second idea since it is pretty lightweight and requires no new implementation. – BeeOnRope Mar 16 '17 at 22:32