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.