Предположение
Вопрос в том, как улучшить время работы вашего программного обеспечения, поскольку оно очень медленное.
Выполняется после двух изменения кода ускоряют ваш код
- Вместо того, чтобы хранить список простых чисел, проверяйте числа как простые (истинные) или не простые (ложные)
- проверяйте только нечетные числа> 2 для простого
Код
def sieve_of_Eratosthenes2(n):
if n < 2:
return []
if n < 3:
return [2]
L = [True] * (n+1) # all numbers set as primes initially
# modifies prime flag in list for odd numbers
for i in range(3, n, 2): # Check odd numbers for prime (no need to check even numbers)
if L[i]: # A prime
L[i*i::i] = [False]*len(L[i*i::i]) # from i^2 in increments of i
# Report prime 2 + odd primes
return [2] + [i for i in range(3, n, 2) if L[i]] # Get odd numbers whose flag is
# still True
Новый код
%timeit sieve_of_Eratosthenes2(1000)
188 µs ± 16.6 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
%timeit sieve_of_Eratosthenes2(100000)
16 ms ± 1.58 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
In going from 1, 000 to 100, 000 time
(i.e. 100X), time increased by ~85,
so almost linear
Старый код
%timeit sieve_of_Eratosthenes(1000)
25.2 ms ± 1.59 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
sieve_of_Eratosthenes2(100000)
261.45 seconds (using time module)
In going from 1, 000 to 100, 000 (100X)
time increased by factor of ~10, 000
So quadratic increase in time (i.e. 100^2).
Пояснение
Сложность Сито Эратосфена составляет
O(N log (log N))
Что почти линейно , поскольку операции обычно O (1), чтобы пометить числа в массиве как True (простое число) и False (не простое число).
В исходном алгоритме числа не простые числа были удалены, а не помечены, что занимает :
O(N) per removal.
Это добавляет дополнительный коэффициент N к сложности Сита Эратосфена, в результате чего оригинальная сложность алгоритма составляет: * 1 046 *
O(N*N*log (log N))
Таким образом, почти квадратично c, что подтверждается временем выполнения.