lambda is slower than function call in python, why

前端 未结 3 1517
清酒与你
清酒与你 2021-02-20 18:20

I think lambda is faster than function call, but after testing, I find out that I am wrong. Function call is definitely faster than lambda call.

Can anybody tell me why

相关标签:
3条回答
  • 2021-02-20 18:45

    There's no difference in calling a lambda versus a function. A lambda is just a function created with a single expression and no name.

    Say we have two identical functions, one created with a function definition, the other with a lambda expression:

    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. 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.

    Timing it

    Here's how I would examine the timings.

    Timeit's timeit and repeat both take a callable:

    import timeit
    

    Note that timeit.repeat takes a repeat argument as well:

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

    These differences are too small to be significant.

    0 讨论(0)
  • 2021-02-20 18:51

    As pointed out above, your first test only profiles the time it takes to define 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:

    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
    
    0 讨论(0)
  • 2021-02-20 18:58

    timeit('def a(): return [].extend(range(10)) ;a()') is not calling a(); The call to a() is part of the definition of 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
    
    0 讨论(0)
提交回复
热议问题