I've implemented a Segmented Sieve of Eratosthenes that assumes each segment is about length \$ \sqrt{N}\$ for some upper limit \$N\$.
I further optimized the function by skipping all the evens when sieving.
I'd like to know if anyone has any views or advice on further optimizing my implementation.
Note that there are three functions: the first, "SieveEratList" is a standard Sieve of Eratosthenes (to calculate primes in range \$ [1, \sqrt{N}] \$); the second, "find_first_multiple_odds", checks to find the initial index value in an interval of odd numbers (since we're skipping evens); and the third, "OptiSegment," is the optimized Segmented Sieve that calls the previous two when needed.
I'm open to any suggestions, whether it's space optimization or runtime optimization.
def SieveEratList(n):
numbers = [False]*2+[True]*(n-2)
result = []
for index, prime_candidate in enumerate(numbers):
if prime_candidate:
result.append(index)
for x in range(index*index, n, index):
numbers[x] = False
return result
def find_first_multiple_odds(p, low):
# O(1)
x = p*((low/p)+(low%p != 0))
x += p*(x%2 == 0)
return ((x-low)/2)
def OptiSegment(high):
delta = int(high**0.5)+1*(int(high**0.5)%2)
seed_primes = SieveEratList(delta+1)
#boolean operator checks see if "high" is square
segment_count = int(high/delta) - 1*((high**0.5)-int(high**0.5) == 0.0)
for seg in range(1, segment_count+1):
low_val = seg*delta+1
top_val = delta*(seg+1)-1
candidates = list(range(low_val, top_val+1, 2))
prime_limit = top_val**0.5+1
Q = iter(seed_primes)
p = next(Q)
p = next(Q)
while p < prime_limit:
q = find_first_multiple_odds(p, low_val)
for i in range(q, delta/2, p):
candidates[i] = False
p = next(Q)
seed_primes += [x for x in candidates if (x and x < high)]
return seed_primes