Ускорение итерации генератора над списком - PullRequest
0 голосов
/ 18 июня 2020

У меня есть две функции на 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 секунды медленнее при повторении по нему. Ожидается ли это, или я что-то делаю неправильно?

Я подумал, что, поскольку генератор может создавать список быстрее, чем сито без генератора, я мог бы перебирать его быстрее, но это не так.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...