Python中有“太多的yield语句”吗?
如果执行一个目录列表并读取其中的文件,与返回目录中所有文件的列表相比,yield的性能开始恶化的几点?Python中有“太多的yield语句”吗?
在这里我假设一个有足够的内存来返回(可能是巨大的)列表。
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更快。
这取决于你如何做目录列表。 Python中的大多数机制将整个目录列表拖入列表中;如果这样做,那么即使是单一产量也是浪费。根据XKCD对“random”的定义,如果使用opendir(3)
,那么它可能是一个随机数。
谢谢。 我在os.listdir和os.walk之间进行了辩论,但我认为这一点现在没有意义(从性能的角度来看)。 更一般地说,是否有太多产量成为问题的情况(例如,由于python的实现假设?) – saidimu 2010-02-25 00:03:07
当然没有想到的东西。 – 2010-02-25 00:06:11
yield
的进一步使用导致性能下降没有意义。实际上,与汇总列表相比,yield
实际上通过比较存在的更多元素而得到提高。
使用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
在Python 2.7,中glob
的定义是
def glob(pathname): return list(iglob(pathname))
所以至少这个版本,glob
永远不会比iglob
更快。
你有代码可以分享这可能说明你的关注? – 2010-02-25 00:01:58
@saidimu:我正在看那个页面,但是我看不到它说'iglob()'更快。它说'iglob()'返回结果*“而不是实际同时存储它们”*但这并不意味着性能方面的任何暗示。 – 2010-02-25 00:53:42
我会假设不必同时存储它们都具有正面的速度(和内存)影响? – saidimu 2010-02-25 01:00:33