您好, 欢迎来到 !    登录 | 注册 | | 设为首页 | 收藏本站

Python:生成器表达式与产量

Python:生成器表达式与产量

两者之间只有细微的差别。您可以使用该dis模块自己检查这种事情。

我的第一个版本反编译了在交互式提示符下在module- scope上创建的生成器表达式。这与在函数内部使用的OP版本略有不同。我已对此进行了修改,以匹配问题中的实际情况。

如下所示,“ yield”生成器(第一种情况)在设置中具有三个额外的指令,但与第一个指令相比,FOR_ITER它们仅在一个方面有所不同:“ yield”方法在循环内部使用LOAD_FAST代替LOAD_DEREF。的LOAD_DEREF“而较慢的”LOAD_FAST,所以它使得“产量”版本略快于对的足够大的值的生成器表达式x(外环),因为该值y是稍快于每遍加载。对于较小的值,x由于设置代码的额外开销,它会稍微慢一些。

值得指出的是,生成器表达式通常将在代码中内联使用,而不是将其与此类函数包装在一起。这将消除一些设置开销,并使生成器表达式对于较小的循环值稍快一些,即使在其他情况下LOAD_FAST给“ yield”版本带来了好处。

在任何一种情况下,性能差异都不足以证明在一个或另一个之间做出决定是合理的。可读性的重要性要大得多,因此请使用对当前情况最易读的方式。

>>> def Generator(x, y):
...     for i in xrange(x):
...         for j in xrange(y):
...             yield(i, j)
...
>>> dis.dis(Generator)
  2           0 SETUP_LOOP              54 (to 57)
              3 LOAD_GLOBAL              0 (xrange)
              6 LOAD_FAST                0 (x)
              9 CALL_FUNCTION            1
             12 GET_ITER
        >>   13 FOR_ITER                40 (to 56)
             16 STORE_FAST               2 (i)

  3          19 SETUP_LOOP              31 (to 53)
             22 LOAD_GLOBAL              0 (xrange)
             25 LOAD_FAST                1 (y)
             28 CALL_FUNCTION            1
             31 GET_ITER
        >>   32 FOR_ITER                17 (to 52)
             35 STORE_FAST               3 (j)

  4          38 LOAD_FAST                2 (i)
             41 LOAD_FAST                3 (j)
             44 BUILD_TUPLE              2
             47 YIELD_VALUE
             48 POP_TOP
             49 JUMP_ABSOLUTE           32
        >>   52 POP_BLOCK
        >>   53 JUMP_ABSOLUTE           13
        >>   56 POP_BLOCK
        >>   57 LOAD_CONST               0 (None)
             60 RETURN_VALUE
>>> def Generator_expr(x, y):
...    return ((i, j) for i in xrange(x) for j in xrange(y))
...
>>> dis.dis(Generator_expr.func_code.co_consts[1])
  2           0 SETUP_LOOP              47 (to 50)
              3 LOAD_FAST                0 (.0)
        >>    6 FOR_ITER                40 (to 49)
              9 STORE_FAST               1 (i)
             12 SETUP_LOOP              31 (to 46)
             15 LOAD_GLOBAL              0 (xrange)
             18 LOAD_DEREF               0 (y)
             21 CALL_FUNCTION            1
             24 GET_ITER
        >>   25 FOR_ITER                17 (to 45)
             28 STORE_FAST               2 (j)
             31 LOAD_FAST                1 (i)
             34 LOAD_FAST                2 (j)
             37 BUILD_TUPLE              2
             40 YIELD_VALUE
             41 POP_TOP
             42 JUMP_ABSOLUTE           25
        >>   45 POP_BLOCK
        >>   46 JUMP_ABSOLUTE            6
        >>   49 POP_BLOCK
        >>   50 LOAD_CONST               0 (None)
             53 RETURN_VALUE
python 2022/1/1 18:36:14 有238人围观

撰写回答


你尚未登录,登录后可以

和开发者交流问题的细节

关注并接收问题和回答的更新提醒

参与内容的编辑和改进,让解决方法与时俱进

请先登录

推荐问题


联系我
置顶