For drastic speedup for the primes generator, use itertools.takewhile and stop at sqrt of candidate:
import itertools
from utils import timing
@timing
def primes(n):
""" primitive non-sieve prime finder """
p = [2, 3]
candidate, step = 5, 2
while candidate <= n:
if all(candidate % pr for pr in itertools.takewhile(lambda x: x * x <= candidate, p)):
p.append(candidate)
candidate += step
# consider only number % 6 in (1,5) ie 6*n +- 1
step = 2 if step == 4 else 4
return p
print(len(primes(10**5)))
Timing before and after:
primes took 15.643 s
9592
primes took 632 ms
9592
The timing decoreator in utils.py
import time
def timing(func):
def wrapper(*arg):
t1 = time.clock()
res = func(*arg)
t2 = time.clock()
print('%s took %s' % (func.__name__, timestr(t2-t1)))
return res
wrapper.__doc__, wrapper.__name__, wrapper.__module__ = func.__doc__, func.__name__, func.__module__
return wrapper
Does not compare so well still with fastest numpy based sieve:
Primes upto 1000000
primes took 11.997 s
78498
fastprimes took 172.043 ms
78498
>>>
pyTony
pyMod
6,308 posts since Apr 2010
Reputation Points: 879
Solved Threads: 986
Skill Endorsements: 26