Python中有“过多的yield语句”这种说法吗?
如果你在做一个文件夹的文件列表,并且要读取里面的文件,那么在什么情况下,使用“生成器”(yield)的方法性能会开始变差,相比于直接返回一个包含所有文件的列表呢?
在这里,我假设你的电脑有足够的内存来返回这个可能非常大的文件列表。
顺便说一下,我在评论中插入代码时遇到了一些问题,所以我会在这里放一些例子。
def list_dirs_list():
# list version
return glob.glob(/some/path/*)
def list_dirs_iter():
# iterator version
return glob.iglob(/some/path/*)
实际上,这两种调用方式都使用了os.listdir,所以在性能上看起来是一样的。但是这份Python文档似乎暗示使用glob.iglob会更快。
4 个回答
1
使用yield的效果和写一个函数对象类差不多,从实现和性能的角度来看也是如此。只是使用yield可能会比自己写的类中的__call__
方法调用得更快,因为yield是直接在生成器的C语言实现中内置的。
为了更清楚地说明这一点,下面的用法和大致实现是一样的:
def generator_counter():
i = 0
while True:
i += 1
yield i
class functor_counter():
def __init__(self):
self.i = 0
def __call__(self):
i += 1
return i
5
使用yield
没有哪个时刻会导致性能下降。实际上,跟把所有东西放在一个列表里相比,使用yield
的效果会更好,尤其是当元素数量增加的时候。
2
这要看你是怎么列出目录的。大多数情况下,Python会把整个目录的内容都放到一个列表里;如果是这样的话,即使你只用了一次“yield”,也是浪费。如果你使用的是 opendir(3)
,那么根据XKCD对“随机”的定义,它可能就是一个随机的数字。