Я пытаюсь оптимизировать дальнейшее решение в потоке простых чисел, вынимая сложную формулу для длины подсписка.len () одной и той же подпоследовательности слишком медленный, так как len дорог, а генерация подпоследовательности дорогая.Это выглядит немного ускорить функцию, но я еще не мог убрать деление, хотя делаю только внутри оператора условия.Конечно, я мог бы попытаться упростить вычисление длины, убрав оптимизацию начальной разметки для n вместо n * n ...
Я заменил деление / на целочисленное деление // для совместимости с Python 3 или
from __future__ import division
Также мне было бы интересно, если бы эта формула повторения могла помочь ускорить решение numpy, но у меня нет большого опыта использования numpy.
Если вы включили psyco для кодаОднако история становится совершенно другой, и ситовый код Аткинса становится быстрее, чем эта специальная техника нарезки.
import cProfile
def rwh_primes1(n):
# /2029352/samyi-bystryi-sposob-perechislit-vse-prostye-chisla-nizhe-n#2029364
""" Returns a list of primes < n """
sieve = [True] * (n//2)
for i in xrange(3,int(n**0.5)+1,2):
if sieve[i//2]:
sieve[i*i//2::i] = [False] * ((n-i*i-1)//(2*i)+1)
return [2] + [2*i+1 for i in xrange(1,n/2) if sieve[i]]
def primes(n):
# /2029352/samyi-bystryi-sposob-perechislit-vse-prostye-chisla-nizhe-n#2029364
# recurrence formula for length by amount1 and amount2 Tony Veijalainen 2010
""" Returns a list of primes < n """
sieve = [True] * (n//2)
amount1 = n-10
amount2 = 6
for i in xrange(3,int(n**0.5)+1,2):
if sieve[i//2]:
## can you make recurrence formula for whole reciprocal?
sieve[i*i//2::i] = [False] * (amount1//amount2+1)
amount1-=4*i+4
amount2+=4
return [2] + [2*i+1 for i in xrange(1,n//2) if sieve[i]]
numprimes=1000000
print('Profiling')
cProfile.Profile.bias = 4e-6
for test in (rwh_primes1, primes):
cProfile.run("test(numprimes)")
Профилирование (не так много различий между версиями)
3 function calls in 0.191 CPU seconds
Ordered by: standard name
ncalls tottime percall cumtime percall filename:lineno(function)
1 0.006 0.006 0.191 0.191 <string>:1(<module>)
1 0.185 0.185 0.185 0.185 myprimes.py:3(rwh_primes1)
1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects}
3 function calls in 0.192 CPU seconds
Ordered by: standard name
ncalls tottime percall cumtime percall filename:lineno(function)
1 0.006 0.006 0.192 0.192 <string>:1(<module>)
1 0.186 0.186 0.186 0.186 myprimes.py:12(primes)
1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects}
Интересно, что с увеличениемограничение до 10 ** 8 и установка декоратора синхронизации для функций, удаляющих профилирование:
rwh_primes1 took 23.670 s
primes took 22.792 s
primesieve took 10.850 s
Интересно, что если вы не создаете список простых чисел, а возвращаете само сито, время составляет примерно половину от версии списка чисел.