After getting through some of the SO posts, i found Sieve of Eratosthenes is the best & fastest way of generating prime numbers.
I want to generate the prime num
There are two basic choices here: sieve the range [a..b]
by primes below sqrt(b)
(the "offset" sieve of Eratosthenes), or by odd numbers. That's right; just eliminate the multiples of each odd as you would of each prime. Sieve the range in one chunk, or in several "segments" if the range is too wide (but efficiency can deteriorate if the chunks are too narrow).
In Haskell executable pseudocode,
primesRange_by_Odds a b = foldl (\r x-> r `minus` [q x, q x+2*x..b])
[o,o+2..b]
[3,5..floor(sqrt(fromIntegral b))]
where
o = 1 + 2*div a 2 -- odd start of range
q x = x*x - 2*x*min 0 (div (x*x-o) (2*x)) -- 1st odd multiple of x >= x*x in range
Sieving by odds will have the additional space complexity of O(1) (on top of the output / range). That is because we can enumerate the odds just by iteratively adding 2 — unlike primes of sieve of Eratosthenes, below sqrt(b)
, for which we have to reserve additional space of O(pi(sqrt(b))) = ~ 2*sqrt(b)/log(b)
(where pi()
is a prime-counting function).
Sorenson Sieve might be worth a peek if space complexity is really an issue. Got the reference from the wikipedia page you shared.
If you have enough space to store all the primes up to sqrt(b) then you can sieve for the primes in the range a to b using additional space O(b-a).
In Python this might look like:
def primesieve(ps,start,n):
"""Sieve the interval [start,start+n) for primes.
Returns a list P of length n.
P[x]==1 if the number start+x is prime.
Relies on being given a list of primes in ps from 2 up to sqrt(start+n)."""
P=[1]*n
for p in ps:
for k in range((-start)%p,n,p):
if k+start<=p: continue
P[k]=0
return P
You could easily make this take half the space by only sieving the odd numbers.
Search for "segmented sieve of Eratosthenes" at your favorite search engine. If you don't want to go searching, I have an implementation at my blog.