python各种素数求法对比
版本1
最朴素的方法,对 2到n的每个数i,确认其是否能被从2到sqrt(i)的数整除
N = 10000
def isPrime(n):
if n<=1:
return False
i = 2
while (i*i<=n):
if n%i == 0:
return False
i+=1
return True
prime_ls = []
for i in range(2,N):
if isPrime(i):
prime_ls.append(i)
版本2
对版本1的改进,排除掉i为偶数的情况
N = 10000
def isPrime(n):
if n<=1:
return False
if n%2 == 0:
return False
i = 3
while (i*i<=n):
if n%i == 0:
return False
i+=2
return True
prime_ls = [2]
for i in range(3,N):
if isPrime(i):
prime_ls.append(i)
版本3
网上最常见的python素数筛法,利用到了python的特性:生成器
N = 10000
def odd_iter():
n = 1
while(True):
n += 2
yield n
def not_divisble(n):
return lambda x: x%n>0
def primes():
yield 2
it = odd_iter()
while(True):
n = next(it)
yield n
it = filter(not_divisble(n),it)
prime_ls = []
for i in primes():
if i >= N:
break
prime_ls.append(i)
注:filter中的 not_divisble(n),不能直接替代为 lambda x: x%n>0,原因未知
版本4
素数筛法
N = 10000
def get_primes(n):
isp = [x%2==1 for x in range(n+1)]
isp[1] = False
isp[2]= True
p = [2]
for i in range(3,n+1,2):
if(isp[i]):
p.append(i)
for j in p:
if(i*j<=n):
isp[i*j] = False
else:
break
if(i%j == 0):
break
return p
prime_ls = get_primes(N)
结果对比
表格中的数据为使用对应版本的算法,求小于N的所有素数所花时间的 m e a n ± s t d mean\pm std mean±std
方法 | N=1000 | N=5000 | N=10000 | N=50000 |
---|---|---|---|---|
版本1 | 604 µ s ± 62.9 µ s 604 µs ± 62.9 µs 604µs±62.9µs | 6.23 m s ± 2.24 m s 6.23 ms ± 2.24 ms 6.23ms±2.24ms | 11.8 m s ± 778 µ s 11.8 ms ± 778 µs 11.8ms±778µs | 108 m s ± 8.47 m s 108 ms ± 8.47 ms 108ms±8.47ms |
版本2 | 378 µ s ± 49.2 µ s 378 µs ± 49.2 µs 378µs±49.2µs | 2.75 m s ± 230 µ s 2.75 ms ± 230 µs 2.75ms±230µs | 6.5 m s ± 276 µ s 6.5 ms ± 276 µs 6.5ms±276µs | 59.3 m s ± 9.29 m s 59.3 ms ± 9.29 ms 59.3ms±9.29ms |
版本3 | 1.64 m s ± 165 µ s 1.64 ms ± 165 µs 1.64ms±165µs | 23.3 m s ± 1.46 m s 23.3 ms ± 1.46 ms 23.3ms±1.46ms | 81.8 m s ± 7 m s 81.8 ms ± 7 ms 81.8ms±7ms | 1.4 s ± 66.6 m s 1.4 s ± 66.6 ms 1.4s±66.6ms |
版本4 | 224 µ s ± 64.6 µ s 224 µs ± 64.6 µs 224µs±64.6µs | 1.03 m s ± 37.6 µ s 1.03 ms ± 37.6 µs 1.03ms±37.6µs | 2.07 m s ± 100 µ s 2.07 ms ± 100 µs 2.07ms±100µs | 11 m s ± 467 µ s 11 ms ± 467 µs 11ms±467µs |