Как я могу оптимизировать скорость этого сита Mersenne Prime в Python?

Мне нужна помощь в отношении сита Мерсенна Прайм, которое я отредактировал для выполнения этой задачи; этот код из идеального генератора чисел. Проблема в том, что программа тормозит на 11213 в питоне. Может ли кто-нибудь предложить некоторые улучшения скорости для этого сита? Вывод начинается так. 2 3 5 7 13 17 19 31 61 89 107 127 521 607 1279 2203 2281 3217 4253 4423 9689 9941 11213

from itertools import count

def postponed_sieve():                   # postponed sieve, by Will Ness      
yield 2; yield 3; yield 5; yield 7;   # original code David Eppstein, 
sieve = {}                           #   Alex Martelli, ActiveState Recipe 
#2002
ps = postponed_sieve()               # a separate base Primes Supply:
p = next(ps) and next(ps)            # (3) a Prime to add to dict
q = p*p                              # (9) its sQuare 
for c in count(9,2):                 # the Candidate
    if c in sieve:               # c's a multiple of some base prime
        s = sieve.pop(c)         #     i.e. a composite ; or
    elif c < q:  
         yield c                 # a prime
         continue              
    else:    #(c==q)            # or the next base prime's square:
        s=count(q+2*p,2*p)       #    (9+6, by 6 : 15,21,27,33,...)
        p=next(ps)               #    (5)
        q=p*p                    #    (25)
    for m in s:                  # the next multiple 
        if m not in sieve:       # no duplicates
            break
    sieve[m] = s                 # original test entry: ideone.com/WFv4f

def prime_sieve():                   # postponed sieve, by Will Ness      
yield 2; yield 3; yield 5; yield 7;   # original code David Eppstein, 
sieve = {}                           #   Alex Martelli, ActiveState Recipe 
#2002
ps = postponed_sieve()               # a separate base Primes Supply:
p = next(ps) and next(ps)            # (3) a Prime to add to dict
q = p*p                              # (9) its sQuare 
for c in count(9,2):                 # the Candidate
    if c in sieve:               # c’s a multiple of some base prime
        s = sieve.pop(c)         #     i.e. a composite ; or
    elif c < q:  
         yield c                 # a prime
         continue              
    else:    #(c==s)            # or the next base prime’s square:
        s=count(q+2*p,2*p)       #    (9+6, by 6 : 15,21,27,33,...)
        p=next(ps)               #    (5)
        q=p*p                    #    (25)
    for m in s:                  # the next multiple 
        if m not in sieve:       # no duplicates
            break
    sieve[m] = s                 # original test entry: ideone.com/WFv4f

def mod_mersenne(n, prime, mersenne_prime):
while n > mersenne_prime:
    n = (n & mersenne_prime) + (n >> prime)
if n == mersenne_prime:
    return 0
return n

def is_mersenne_prime(prime, mersenne_prime):
s = 4
for i in range(prime - 2):
    s = mod_mersenne((s*s - 2), prime, mersenne_prime)
return s == 0

def calculate_perfects():
yield(2)
primes = prime_sieve()
next(primes)                     #2 is barely even a prime
for prime in primes:
    if is_mersenne_prime(prime, 2**prime-1):
        yield(prime)

if __name__ == '__main__':
for perfect in calculate_perfects():
    print(perfect)


#edited by Tom E. O'Neil to find Mprimes

person Tom E. O'Neil    schedule 16.05.2018    source источник
comment
Зачем 2 копии одной и той же функции? Почему ни один из них не имеет отступа должным образом?   -  person Scott Hunter    schedule 16.05.2018
comment
Но, пожалуйста, исправьте отступ.   -  person PM 2Ring    schedule 16.05.2018
comment
Привет, Скотт, у меня проблемы с публикацией кода здесь, это немного запутанно для меня, я попробую, хорошо. Может ли этот код иметь только одну функцию?   -  person Tom E. O'Neil    schedule 16.05.2018
comment
Ваши postponed_sieve и prime_sieve содержат идентичный код (кроме имени самой функции, что важно в рекурсивных функциях). Но я не вижу смысла в навороченном первичном генераторе. Простое сито, например это, достаточно быстро для небольших простых чисел, которые вам нужны.   -  person PM 2Ring    schedule 16.05.2018
comment
Вы можете немного ускорить этот простой тест Лукаса-Лемера Мерсенна, встроив mod_mersenne в is_mersenne_prime. Но особого прироста скорости вы не увидите. В конце концов, к тому времени, как вы доберетесь до prime=11213, связанное с ним mersenne_prime станет довольно большим (3376 десятичных цифр), а вычисления с такими большими целыми числами требуют времени.   -  person PM 2Ring    schedule 16.05.2018
comment
Привет, Скотт, не могли бы вы опубликовать встроенный код для mod_mersenne? Я все еще в замешательстве.   -  person Tom E. O'Neil    schedule 17.05.2018