How to generate a vector [1, 2, 3 ..., N] efficently?

My question is simple here:
How to generate a vector [1, 2, 3 ..., N] efficently?
Any speed up idea would be okay. (SIMD?)
Assume to build such a vector in runtime, because N is known only in runtime.

1
2
3
4
5
  /// My current idea
std::vector<uint64_t> vec;
vec.reserve(N);
vec.resize(N);
        std::generate(vec.begin(), vec.end(), [n = 0] () mutable { return n++; });
Last edited on
http://www.cplusplus.com/reference/numeric/iota/

1
2
3
4
5
6
7
8
9
10
11
12
13
#include <iostream>
#include <vector>
#include <numeric>
using namespace std;

int main()
{
   int N;
   cout << "Input N: ";   cin >> N;
   vector<int> V( N );
   iota( V.begin(), V.end(), 1 );
   for ( int i : V ) cout << i << ' ';
}
Last edited on
if you are declaring it where you know N, just do it all at once:
std::vector<uint64_t> vec(N);

what is the scenario?
is this in a function call, and you re-created this thing frequently?
Does N change?
if its 1-n, maybe std::iota is faster, but I do not know. It may be the same.

what are you doing? You may not need to store these at all if 1-n is really the answer, and not an example.
Last edited on
grumbles about how I wasted 5 minutes trying to find iota in <algorithm>, not knowing it was defined in <numeric>

CakeByTheOcean, you should either reserve and push_back, or do resize (or construct directly). I imagine both will be about equal in performance. But doing a reserve and then a resize is pointless. It's not really harmful, just unnecessary.

btw, if you look into the assembly generated with optimization turned on, I believe compilers will generate simd instructions.
https://godbolt.org/

But above all, measure. Do a measurement of which implementation is the most efficient, and at different values of n.
Last edited on
Use std::iota in <numeric>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <iostream>
#include <vector>
#include <numeric> // std::iota

int main()
{
   // let's choose some arbitrary number for N
   const int N = 52;

   std::vector<int> vec(N);

   // fills the vector from 1 to N
   std::iota(vec.begin(), vec.end(), 1);

   // let's confirm the vector has been filled correctly
   for (size_t loop = 0; loop < vec.size(); loop++)
   {
      std::cout << vec.at(loop) << '\t';

      if (0 == (loop + 1) % 10)
      {
         std::cout << '\n';
      }
   }
   std::cout << '\n';
}

1       2       3       4       5       6       7       8       9       10
11      12      13      14      15      16      17      18      19      20
21      22      23      24      25      26      27      28      29      30
31      32      33      34      35      36      37      38      39      40
41      42      43      44      45      46      47      48      49      50
51      52


http://www.cplusplus.com/reference/numeric/iota/
Well... if you absolutely positively must optimize the process of setting each element of an array (or vector) to an increasing sequence, you could do something like this:

1
2
3
4
5
6
7
8
9
10
#include <vector>
#include <algorithm>
#include <execution>

int main() {
  const int N = 100'000'000;
  std::vector<int> ints(N);
  auto arriota = [&](int &in) {in = 1 + &in - ints.data();};
  std::for_each(std::execution::par_unseq, ints.begin(), ints.end(), arriota);
}


-Albatross
> generate a vector [1, 2, 3 ..., N]
> [n = N] () mutable { return n++; }
¿did you even try what you wrote?
that generates the range [N, 2N)
Topic archived. No new replies allowed.