You mark multiples of pimes in the seive with:
for (int j = i * i; j <= n; j += i) {
input[j] = false;
}
Say i = 5 then you mark 25, 30, 35, 40, 45, 50, 55, 60 ...
You might notice that every second number is a multiple of 2. No need to mark them since they are never tested for inclusion later on. So use j += 2 * i
.
If you use the trick to skip multiples of 2 and 3 then you can use that here too, advancing by 2 * i
and 4 * i
alternatively. But you have to compute with which one to start. Actually I would advance by 6 * i
and set input[j] and input[j - 2 * i]. This time you have to compute the right starting point (i * i
or (i + 2) * i
) instead of the right step.
I also have another idea in mined that i always wanted to try and benchmark.
In the current code you start by creating a seive of the full size and fully initialize it. Then you mark off multiples of primes. The above answeres already eliminated a lot of duplicate marking but I think one can do better.
Note: There is no need to store even numbers in the seive but it's easier to explain things with them in it. Compressing the seive to skip even numbers is left as exercise.
Start with a seive of 2 * 3 * 5 = 30
and mark it as before (mark 5 * 5 = 25
). The next prime is 7. Grow the seive to 2 * 3 * 5 * 7 = 210
. The first 30 entries are copied repeadately to fill the seive. Then mark 7. The next prime is 11. Grow the seive to 2 * 3 * 5 * 7 * 11 = 2310
, again by copying the first 210 entries. For every prime you find you grow the seive up to the final size you need, which should happen quickly (max 27 for 32bit, 47 for 64bit systems).
Using memcpy to grow the seive could be faster than initializing it at start and the loops to mark individual multiples of primes. It only helps for the first few primes but those are the ones with the most work.
std::vector<bool>
is specialized and does not conform to normal container semantics. It is specifically optimized for size and as such has very poor speed characteristics. You may want to trystd::vector<char>
\$\endgroup\$