简体   繁体   English

lambda比python中的函数调用慢,为什么呢

[英]lambda is slower than function call in python, why

I think lambda is faster than function call, but after testing, I find out that I am wrong. 我认为lambda比函数调用更快,但经过测试,我发现我错了。 Function call is definitely faster than lambda call. 函数调用肯定比lambda调用快。

Can anybody tell me why? 谁能告诉我为什么?

And how to speed up function call in Python? 以及如何加速Python中的函数调用?

I'm using Ubuntu 14.04 and Python 2.7.6 我正在使用Ubuntu 14.04和Python 2.7.6

>>> timeit('def a():return 222*333 ;a()')
0.08195090293884277
>>> timeit('a=lambda:222*333 ;a()')
0.11071300506591797

>>> timeit('a=lambda: [].extend(range(10)) ;a()')
0.40241098403930664
>>> timeit('a=lambda: [].extend(range(10)) ;a()')
0.4011270999908447
>>> timeit('a=lambda: [].extend(range(10)) ;a()')
0.4064619541168213
>>> timeit('def a(): return [].extend(range(10)) ;a()')
0.07965493202209473
>>> timeit('def a(): return [].extend(range(10)) ;a()')
0.08039593696594238
>>> timeit('def a(): return [].extend(range(10)) ;a()')
0.08103609085083008
>>> timeit('def a(): return [].extend(range(10)) ;a()')
0.08639097213745117

Sorry for my mistake, there is no difference. 对不起我的错误,没有区别。 Correct testing: 正确的测试:

>>> timeit('a()', setup="def a():return 222*333")
0.07061290740966797
>>> timeit('a()', setup="a=lambda: 222*333")
0.06967616081237793

timeit('def a(): return [].extend(range(10)) ;a()') is not calling a() ; timeit('def a(): return [].extend(range(10)) ;a()')不调用a() ; The call to a() is part of the definition of a : 要将呼叫a()是这样定义的一部分, a

In [34]: def a(): return [].extend(range(10)) ;a()

In [35]: import dis

In [36]: dis.dis(a)
  1           0 BUILD_LIST               0
              3 LOAD_ATTR                0 (extend)
              6 LOAD_GLOBAL              1 (range)
              9 LOAD_CONST               1 (10)
             12 CALL_FUNCTION            1
             15 CALL_FUNCTION            1
             18 RETURN_VALUE        
             19 LOAD_GLOBAL              2 (a)
             22 CALL_FUNCTION            0       #<-- a is called
             25 POP_TOP             

If you test the pieces separately, the difference is negligible: 如果您单独测试这些部分,差异可以忽略不计:

In [24]: %timeit a=lambda: [].extend(range(10))
10000000 loops, best of 3: 68.6 ns per loop

In [25]: %timeit def a2(): return [].extend(range(10))
10000000 loops, best of 3: 68.8 ns per loop

In [22]: %timeit a()
1000000 loops, best of 3: 445 ns per loop

In [23]: %timeit a2()
1000000 loops, best of 3: 442 ns per loop

As pointed out above, your first test only profiles the time it takes to define a . 如上所述,您的第一个测试仅描述定义 a所需的时间。 It's actually never called. 它实际上从未被调用过。

Lambda expressions and "normal" functions generate the exact same bytecode, as you can see if you use the dis module: Lambda表达式和“普通”函数生成完全相同的字节码,如果使用dis模块,可以看到:

def a(): return 10
b = lambda: 10

import dis

>>> dis.dis(a)
1           0 LOAD_CONST               1 (10)
            3 RETURN_VALUE
>>> dis.dis(b)
1           0 LOAD_CONST               1 (10)
            3 RETURN_VALUE

There's no difference in calling a lambda versus a function. 调用lambda与函数没有区别。 A lambda is just a function created with a single expression and no name. lambda只是一个用单个表达式创建的函数,没有名称。

Say we have two identical functions, one created with a function definition, the other with a lambda expression: 假设我们有两个相同的函数,一个用函数定义创建,另一个用lambda表达式:

def a():
    return 222*333

b = lambda: 222*333

We see that both are the same type of function object and they both share equivalent byte-code: 我们看到两者都是相同类型的函数对象,它们都共享等效的字节码:

>>> type(a)
<class 'function'>
>>> type(b)
<class 'function'>

>>> import dis
>>> dis.dis(a)
  2           0 LOAD_CONST               3 (73926)
              2 RETURN_VALUE
>>> dis.dis(b)
  1           0 LOAD_CONST               3 (73926)
              2 RETURN_VALUE

How can you speed that up? 你怎么能加快速度呢? You don't. 你没有。 It's Python. 这是Python。 It's pre-optimized for you. 它是为您预先优化的。 There's nothing more for you to do with this code. 您无需再使用此代码了。

Perhaps you could give it to another interpreter, or rewrite it in another language, but if you're sticking to Python, there's nothing more to do now. 也许你可以把它交给另一个解释器,或者用另一种语言重写它,但如果你坚持使用Python,那么现在就没有什么可做的了。

Timing it 定时吧

Here's how I would examine the timings. 这是我如何检查时间。

Timeit's timeit and repeat both take a callable: Timeit的timeitrepeat都可以调用:

import timeit

Note that timeit.repeat takes a repeat argument as well: 请注意, timeit.repeat使用repeat参数:

>>> min(timeit.repeat(a, repeat=100))
0.06456905393861234
>>> min(timeit.repeat(b, repeat=100))
0.06374448095448315

These differences are too small to be significant. 这些差异太小而不显着。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM