|
|
|
|
|
|
j = i*i ; j<n ; j += i
, stepping only on the multiples. Then the number of pass would follow the harmonic series, giving you O(n lg n)
--------- clang++/libc++ ------------ sieve of sundaram: last prime < 32000000 == 31999939 processor time: 1050 milliseconds. sieve of eratosthenes (i*i): last prime < 32000000 == 31999939 processor time: 1090 milliseconds. sieve of eratosthenes (i*2): last prime < 32000000 == 31999939 processor time: 1450 milliseconds. --------- g++/libstdc++ ------------- sieve of sundaram: last prime < 32000000 == 31999939 processor time: 1050 milliseconds. sieve of eratosthenes (i*i): last prime < 32000000 == 31999939 processor time: 1070 milliseconds. sieve of eratosthenes (i*2): last prime < 32000000 == 31999939 processor time: 1450 milliseconds. |
Repeat: it is the use of std::set that is causing the really huge difference in performance. |
|
|
std::cout << "... last prime < " << n ...
std::cout << "... last prime <= " << n ...
--------- clang++/libc++ ------------ sieve of eratosthenes [i<n]: last prime < 32000000 == 31999939 processor time: 1070 milliseconds. sieve of eratosthenes [i<sqrt(n)]: last prime < 32000000 == 31999939 processor time: 980 milliseconds. --------- g++/libstdc++ ------------- sieve of eratosthenes [i<n]: last prime < 32000000 == 31999939 processor time: 1080 milliseconds. sieve of eratosthenes [i<sqrt(n)]: last prime < 32000000 == 31999939 processor time: 930 milliseconds. |
for( std::size_t j = i*i ; j<n ...
does not execute when i >= sqrt(n)const std::size_t m = n / 2
m = (n-1)/2
|
|
n == 97 last prime < 97 == 89 details: m == n/2 == 48 ( (m-1) * 2 + 1 ) == 95 n == 100 last prime < 100 == 97 details: m == n/2 == 50 ( (m-1) * 2 + 1 ) == 99 n == 101 last prime < 101 == 97 details: m == n/2 == 50 ( (m-1) * 2 + 1 ) == 99 n == 102 last prime < 102 == 101 details: m == n/2 == 51 ( (m-1) * 2 + 1 ) == 101 n == 103 last prime < 103 == 101 details: m == n/2 == 51 ( (m-1) * 2 + 1 ) == 101 n == 107 last prime < 107 == 103 details: m == n/2 == 53 ( (m-1) * 2 + 1 ) == 105 n == 108 last prime < 108 == 107 details: m == n/2 == 54 ( (m-1) * 2 + 1 ) == 107 |
|
|
|
|
|
|
this pseudocode eliminates some obvious combinations of odd/even x's/y's in order to reduce computation .... This pseudocode is written for clarity; although some redundant computations have been eliminated ... it still wastes almost half of its quadratic computations on non-productive loops ... To improve its efficiency, a method must be devised to minimize or eliminate these non-productive computations. |
|
|
--------- clang++/libc++ ------------ [int]: last prime < 32000000 == 31999939 sieve size == 128 MB processor time: 1030 milliseconds. [char]: last prime < 32000000 == 31999939 sieve size == 32 MB processor time: 670 milliseconds. --------- g++/libstdc++ ------------- [int]: last prime < 32000000 == 31999939 sieve size == 128 MB processor time: 1030 milliseconds. [char]: last prime < 32000000 == 31999939 sieve size == 32 MB processor time: 600 milliseconds. |
--------- clang++/libc++ ------------ n == 128000000 segment size == 16384 processor time: 350 milliseconds. n == 128000000 segment size == 32768 processor time: 470 milliseconds. n == 128000000 segment size == 65536 processor time: 440 milliseconds. n == 128000000 segment size == 131072 processor time: 480 milliseconds. --------- g++/libstdc++ ------------- n == 128000000 segment size == 16384 processor time: 280 milliseconds. n == 128000000 segment size == 32768 processor time: 320 milliseconds. n == 128000000 segment size == 65536 processor time: 380 milliseconds. n == 128000000 segment size == 131072 processor time: 400 milliseconds. |