gpt4 book ai didi

python - 为什么生成器表达式需要大量内存?

转载 作者:IT老高 更新时间:2023-10-28 22:07:23 25 4
gpt4 key购买 nike

问题

假设我想为小于 20000000 的所有数字找到 n**2

我测试的所有三个变体的常规设置:

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

问题是:

  1. 第一种和第二种解决方案有什么区别?使用 () 会创建一个生成器,那么为什么它需要大量内存呢?
  2. 是否有与我的第三个选项等效的内置函数?

最佳答案

  1. 正如其他人在评论中指出的那样,range 在 Python 2 中创建了一个 list。因此,使用内存,但是生成器使用的 range:

    x = (i**2 for i in range(20000000))  
    # builds a 2*10**7 element list, not for the squares , but for the bases

    >>> sys.getsizeof(range(100))
    872
    >>> sys.getsizeof(xrange(100))
    40
    >>> sys.getsizeof(range(1000))
    8720
    >>> sys.getsizeof(xrange(1000))
    40
    >>> sys.getsizeof(range(20000000))
    160000072
    >>> sys.getsizeof(xrange(20000000))
    40

    这也解释了为什么您的第二个版本(生成器表达式)使用了第一个版本(列表推导式)大约一半的内存,因为第一个版本构建了两个列表(用于底数和正方形),而第二个仅构建了一个碱基列表。

  2. xrange(20000000) 因此,当它返回一个惰性迭代时,极大地提高了内存使用率。这本质上是一种内置内存高效的方式来迭代一系列反射(reflect)您的第三个版本的数字(增加了 startstopstep 的灵 active ):

    x = (i**2 for i in xrange(20000000))

    在 Python 3 中,range 本质上与 Python 2 中的 xrange 相同。但是,Python 3 range 对象具有 Python 2 的 xrange 所没有的一些不错的功能,例如 O(1) 切片,包含,等等。

一些引用资料:

关于python - 为什么生成器表达式需要大量内存?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37156574/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com