Python是否优化lambda x:x

Aar*_*all 3 python lambda

所以我写了一些max/min的代码,它假定生成数据的瓶颈(否则我只是使用maxmin),它需要一个关键函数,如果没有给出使用一个标识函数:

if key is None:
    key = lambda x: x
Run Code Online (Sandbox Code Playgroud)

然后:

for i in iterable:
    key_i = key(i)
Run Code Online (Sandbox Code Playgroud)

而且由于瓶颈在发电机上,问题可能没有实际意义,但如果没有钥匙,我就要求lambda x: x每件物品.我认为Python可以优化此身份功能.有人可以告诉我它是否有效?或者如果没有,它有多贵?有没有办法在不增加行数的情况下更好地完成这项工作(例如三元运算符)?

dde*_*eny 8

好问题 !优化器可以看到foo在某些可预测的条件下可能是一个标识函数,并创建一个替代路径来替换它的已知结果的调用

我们来看看操作码:

>>> def foo(n):
...     f = lambda x:x
...     return f(n)
... 
>>> import dis
>>> dis.dis(foo)
  2           0 LOAD_CONST               1 (<code object <lambda> at 0x7f177ade7608, file "<stdin>", line 2>) 
              3 MAKE_FUNCTION            0 
              6 STORE_FAST               1 (f) 

  3           9 LOAD_FAST                1 (f) 
             12 LOAD_FAST                0 (n) 
             15 CALL_FUNCTION            1 
             18 RETURN_VALUE         
Run Code Online (Sandbox Code Playgroud)

CPython(2.7和3.3测试)似乎没有优化lambda调用.也许另一个实现呢?

>>> dis.dis(lambda x:x)
  1           0 LOAD_FAST                0 (x) 
              3 RETURN_VALUE   
Run Code Online (Sandbox Code Playgroud)

身份功能没有太大作用.因此,每次调用身份函数时,基本上都有2个LOAD_FAST,1个CALL_FUNCTION和1个RETURN_VALUE,而不是创建一个可靠的替代路径(可能比@viraptor所说的解释器更复杂).

也许python代码中的else路径更好.

您在min/max示例中所做的真正优化是通过存储函数的结果来减少函数的调用次数.它现在被称为n次而不是n*4,这是一个公平的收益!

  • 如果没有大量额外的同步成本,它就无法进行优化.`f`在理论上可以在这两行之间改变(实际上在疯狂的应用程序中),因此需要首先从本地检索. (2认同)