发电机的时间效率高吗?

问题描述

我了解python atleast中的生成器是内存有效的,因为它一次处理一个项目,但这如何使它高效(如果有)?

具体来说,假设我正在使用生成器函数来一次为机器学习任务加载一个数据。最后,我仍然需要遍历所有数据元素并一次加载它们(使用生成器函数)。是的,这是内存有效的方法,但是加载整个数据集要比一次加载全部花费更多的时间。我的直觉对吗?

#sample_code

def my_gen():
    for i in range(1000):
    features = np.random.randn(32,32,3)
    labels = np.random.randint(0,1,size = 1)
    yield features,labels

解决方法

将生成器处理为惰性序列,作为相应的渴望序列,通常省时

%timeit sum((x*2 for x in range(5000)))  # lazy generator
366 µs ± 9.24 µs per loop (mean ± std. dev. of 7 runs,1000 loops each)
%timeit sum([x*2 for x in range(5000)])  # eager list
308 µs ± 3.12 µs per loop (mean ± std. dev. of 7 runs,1000 loops each)

这是因为生成器处于中间状态,必须为每个项目恢复中间状态。相反,急于创建序列必须只处理一次中间状态。

但是请记住,发电机的开销基本上是固定的。如果每个项目花费很长时间进行计算,则生成器的恒定开销可以忽略不计。一次处理一个项目时,s还允许释放已处理的项目,从而减少了流程的总体负担-可能在某个时候达到净时间优势。


生成器的优点在于,懒惰可以表示无限的序列和延迟。与序列“普通O”相比,生成器是“ n倍O(i)”。 (你)”。即使整个过程将无限延迟,这也使生成器能够以可靠的时间效率生成每个项目。

无限的渴望序列将具有无限的时间复杂性,但是无限的 lazy 生成器仅根据需要生成项。

def randoms():
    """Infinite stream of random numbers"""
    while True:
        yield random.random()

同样,生成器在提供每个项目之间允许外部数据源时间。当数据源在提供项目之间存在明显的延迟时,这可以使生成器更高效。

,

不。从本质上讲,生成器比类似的替代方法(如列表推导)要慢。

但是

如果您希望通过使用生成器加载数据来减少内存,则可能不必担心这种性能差异。性能瓶颈经常出现在磁盘I / O和/或系统调用上。使用发电机产生的损失在整体性能中的作用微不足道。

因此,最后的答案是:继续使用发电机。它的性能应该是最后要担心的。

,

生成器是您使用的功能。具体任务的实现方式与是否可扩展是一个不同的故事。
您每次可以读取一个项目,并且每次可以读取大量数据并每次都对其进行处理。 因此,根据您的情况,后者可能是更好的选择。在这种情况下,时间效率也会更高。

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...