在python中有“太多的yield语句”这样的东西吗?

时间:2010-02-24 23:45:12

标签: python yield

如果执行目录列表并读取其中的文件,与返回目录中所有文件的列表相比,yield的性能在什么时候开始恶化?

这里我假设有一个足够的RAM来返回(可能是巨大的)列表。

PS我在评论中插入代码时遇到问题,所以我会在这里举一些例子。

def list_dirs_list():
    # list version
    return glob.glob(/some/path/*)

def list_dirs_iter():
    # iterator version
    return glob.iglob(/some/path/*)

在幕后,两次调用glob都使用os.listdir,所以看起来它们在性能方面是相同的。但是this Python doc似乎暗示了glob.iglob更快。

4 个答案:

答案 0 :(得分:5)

没有必要进一步使用yield导致性能下降。事实上,与在列表中组装事物相比,yield实际上通过比较实际上提高了元素。

答案 1 :(得分:2)

这取决于您如何进行目录列表。 Python中的大多数机制将整个目录列表拉入列表中;如果这样做,那么即使单一产量也是浪费。根据XKCD对“随机”的定义,如果使用opendir(3)那么它可能是一个随机数。

答案 2 :(得分:1)

使用yield在功能上类似于编写仿函数类,即使从实现或性能角度来看,除了它实际上可能比自制类上的__call__方法更快地调用生成器,因为它内置于生成器的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

答案 3 :(得分:0)

在Python 2.7中,glob的定义是

def glob(pathname): return list(iglob(pathname))

因此,至少对于此版本,glob永远不会比iglob更快。