У меня есть две функции на inte rnet. Оба являются SieveOfEratosthenes, но один является генератором, а другой - прямым создателем списков. Я вижу разницу в скорости при повторении и меня смущает, потому что генератор работает быстрее, если вы создаете из него полный список. Мне интересно, можно ли перебирать генератор быстрее, так как это было бы очень полезно для меня, поскольку я пытаюсь ускорить некоторый код. Вот функции:
# Generator
def primes_sieve2(limit):
a = [True] * limit
a[0] = a[1] = False
for (i, isprime) in enumerate(a):
if isprime:
yield i
for n in range(i*i, limit, i):
a[n] = False
# Creates complete List
def SieveOfEratosthenes(n):
# Create a boolean array "prime[0..n]" and initialize
# all entries it as true. A value in prime[i] will
# finally be false if i is Not a prime, else true.
prime = [True for i in range(n+1)]
p = 2
while (p * p <= n):
# If prime[p] is not changed, then it is a prime
if (prime[p] == True):
# Update all multiples of p
for i in range(p * p, n+1, p):
prime[i] = False
p += 1
size = 0
for p in range(2, n+1):
if prime[p]:
size+=1
#vv = np.zeros(size, dtype='int64')
vv = []
count = 0
# Print all prime numbers
for p in range(2, n+1):
if prime[p]:
#vv[count] = p
vv.append(p)
count+=1
return vv
Теперь вот различия во времени, генератор быстро создает список, но медленнее при повторении по нему, что меня сбивает, поэтому я подумал, что спрошу чтобы узнать, делаю ли я что-то не так и почему это результат. Вот разница в скорости:
# The generator is slower at iteration
import time
start = time.time()
small_primes2 = primes_sieve2(10000000)
for xx in small_primes2:
xx
end = time.time()
print(end-start)
2.776512861251831
small_primes3 = SieveOfEratosthenes(10000000)
import time
start = time.time()
for xx in small_primes3:
xx
end = time.time()
print(end-start)
0.043845176696777344
# The generator is faster at creating the full list when not iterating.
import time
start = time.time()
small_primes3 = SieveOfEratosthenes(10000000)
end = time.time()
print(end-start)
3.6824228763580322
import time
start = time.time()
small_primes2 = list(primes_sieve2(10000000))
end = time.time()
print(end-start)
2.7591686248779297
Вы можете видеть, что генератор создает список примерно на секунду быстрее, но на 2,3 секунды медленнее при повторении по нему. Ожидается ли это, или я что-то делаю неправильно?
Я подумал, что, поскольку генератор может создавать список быстрее, чем сито без генератора, я мог бы перебирать его быстрее, но это не так.