发电机时间效率高吗?

3

我知道Python中的生成器在处理一个项时是内存高效的,但这如何使其时间高效(如果是的话)?

具体来说,假设我正在使用生成器函数逐个加载机器学习任务所需的数据。最终,我仍然需要循环遍历所有数据元素并逐个加载它们(使用生成器函数)。是的,这样做是内存高效的,但相比一次性全部加载而言,这应该需要更长的时间才能加载整个数据集。我的直觉正确吗?

#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

1
你认为生成器具有时间效率吗?从你正在加载数据集的假设后端能够一次性加载整个数据集吗? - MisterMiyagi
@MisterMiyagi 我不确定生成器是否具有时间效率,这正是我的问题所在。关于评论的后半部分,假设我有一个存储图像数据(像素)的csv文件。我通常使用pandas dataframe一次性加载整个数据,然后对整个dataframe执行一些预处理操作(基本上是向量化)。以上方法的问题在于,如果我的数据集大小为100GB,则必须首先将整个数据集加载到内存中,这样效率不高。 - black sheep 369
继续上一个评论..因此,我能想到的下一个选择是生成器,因为它解决了内存效率的问题,但在这里,我正在循环遍历单个元素,因此我担心可能会失去向量化实现的优势(仅当生成器确实不是时间效率时,我不确定)。 - black sheep 369
看起来像机器学习,因为有“特征”和“标签”。如果你有100GB的数据,可以考虑降维或者制作一个更小的样本数据集。生成器通常不会更快,只是更节省内存。 - Andreas
@Andreas,问题在于即使进行PCA和其他降维处理后,通常仍会有100GB的数据(例如语音数据、视频数据)。而且要进行PCA,我必须先加载数据,对吧?所以我又会遇到内存有限的问题。此外,使用生成器的目的是创建数据批次,然后在每个单独的批次上训练我的模型,但是,像你说的那样,这种方法会使我的系统时间效率更低,因为生成器不是时间效率高的。 - black sheep 369
3个回答

2
将生成器视为一种惰性序列,与相应的急切序列相比,通常时间效率较低
%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)

这是因为生成器保存了中间状态,每个项目都必须恢复该状态。相反,急切地创建一个序列只需处理中间状态一次。
请记住,生成器的开销基本上是固定的。如果每个项目计算需要很长时间,则生成器的恒定开销变得可以忽略不计。当逐个处理项目时,它们还允许释放已处理的项目,从而减少了进程的总负载——在某些情况下可能达到净时间优势。
生成器的优点在于惰性允许表示无限序列和延迟——与序列“纯O(ni)”相比,生成器是“n倍O(i)”。这使得生成器能够以可靠的时间效率产生每个项目,即使整个过程会无限延迟。
无限的急切序列将具有无限的时间复杂度,但无限的惰性生成器仅在需要时生成项目。
def randoms():
    """Infinite stream of random numbers"""
    while True:
        yield random.random()

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

1

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

但是

如果你想通过使用生成器来减少内存加载数据,那么你可能不需要担心这种性能差异。更常见的情况是性能瓶颈出现在磁盘I/O和/或系统调用上。使用生成器带来的惩罚在整体性能中起到可忽略的作用。

因此最终答案是:可以放心使用生成器。其性能应该是最后需要担心的事情。


1

生成器是你使用的一项功能。实现特定任务的方式以及它是否可扩展是不同的问题。
你可以每次读取单个项目,也可以每次读取大量数据并在每次处理它们。
因此,根据您的情况,后者可能是更好的选择。在这种情况下,它也将更加时间有效。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接