Проблема
Предположим, что я хочу найти n**2
для всех чисел, меньших, чем 20000000
.
Общая настройка для всех трех вариантов, которые я тестирую:
import time, psutil, gc
gc.collect()
mem_before = psutil.virtual_memory()[3]
time1 = time.time()
# (comprehension, generator, function)-code comes here
time2 = time.time()
mem_after = psutil.virtual_memory()[3]
print "Used Mem = ", (mem_after - mem_before)/(1024**2) # convert Byte to Megabyte
print "Calculation time = ", time2 - time1
Три параметра для расчета этих чисел:
1. Создание списка через понимание:
x = [i**2 for i in range(20000000)]
Это очень медленно и требует много времени:
Used Mem = 1270 # Megabytes
Calculation time = 33.9309999943 # Seconds
2. Создание генератора с помощью '()'
:
x = (i**2 for i in range(20000000))
Это намного быстрее, чем опция 1, но все еще использует много памяти:
Used Mem = 611
Calculation time = 0.278000116348
3. Определение функции генератора (наиболее эффективно):
def f(n):
i = 0
while i < n:
yield i**2
i += 1
x = f(20000000)
Потребление:
Used Mem = 0
Calculation time = 0.0
Вопросы:
- Какая разница между первым и вторым решениями? Использование
()
создает генератор, поэтому зачем ему нужно много памяти? - Есть ли встроенная функция, эквивалентная моей третьей опции?