29

It is understood that Python lambda functions help in creating anonymous functions. These can be used in other functions like map(), reduce(), filter() and key() in sorting functions. It can also be used to demonstrate and utilise lexical closures.

What I would like to specifically know here is, do lambda functions have a specific advantage over regular functions in terms of their execution times, considering all the other factors to be unchanged?

As I am new to Python, I have tried to understand them by analogously comparing them with the inline functions of C++. Inline functions, as I understand from C++, are useful in saving time as they do not require the necessary "housekeeping tasks" concerned with context switching that occur during function calls and jumps.
Do Python Lambda functions provide with such similar advantages over regular functions?

Some relevant posts that I found useful but not necessarily helpful for my question: Why are Python lambdas useful? Why use lambda functions?

Mel
  • 4,929
  • 10
  • 33
  • 39
bp14
  • 415
  • 3
  • 10

1 Answers1

41

No. The function objects generated by lambda behave exactly like those generated by def. They do not execute any faster. (Also, inline in modern C++ is no longer a directive telling the compiler to inline a function, and has very little to do with inlining.)

If you want, you can take a look at the bytecode disassembly for a lambda and an equivalent def:

import dis

dis.dis(lambda x: x + 2)

print()
def f(x): return x + 2

dis.dis(f)

Output:

  3           0 LOAD_FAST                0 (x)
              3 LOAD_CONST               1 (2)
              6 BINARY_ADD
              7 RETURN_VALUE

  6           0 LOAD_FAST                0 (x)
              3 LOAD_CONST               1 (2)
              6 BINARY_ADD
              7 RETURN_VALUE

No difference. You can also time them:

import timeit

def f(x): return x + 2
g = lambda x: x + 2

print(timeit.timeit('f(3)', globals=globals()))
print(timeit.timeit('g(3)', globals=globals()))

Output:

0.06977041810750961
0.07760106027126312

The lambda actually took longer in this run. (There seems to be some confusion in the comments about whether we're timing enough work to be meaningful. timeit wraps the timed statement in a million-iteration loop by default, so yes, we are.)

Before you ask, no, lambda has no performance disadvantage over def either. The winner of the above race is basically up to luck. lambda and def do have a significant disadvantage over avoiding the use of a callback function entirely, though. For example, map-with-lambda has a significant performance penalty relative to list comprehensions:

import timeit

print(timeit.timeit('list(map(lambda x: x*x, range(10)))'))
print(timeit.timeit('[x*x for x in range(10)]'))

Output:

1.5655903220176697
0.7803761437535286

Whether lambda or def, Python functions are expensive to call.

user2357112 supports Monica
  • 215,440
  • 22
  • 321
  • 400
  • 8
    "map-with-lambda has a significant performance penalty relative to list comprehensions". We don't say that enough – Jean-François Fabre Dec 01 '18 at 08:36
  • @user2357112 Thanks for your reply. The bytecode disassembly and timing outputs are revealing. My current understanding is: lambdas are not particularly advantageous over def functions. They help to make the code more readable(if not always, at least sometimes). It is also a legacy of functional programming choices - Thanks! – bp14 Dec 01 '18 at 10:26
  • 1
    @Jean-FrançoisFabre: maybe, although just looking at the two lines of code side-by-side I prefer the list comprehension regardless of performance. So there's normally no need to talk about it! – Steve Jessop Dec 01 '18 at 14:12
  • ok let me say it again :) `list+map+lambda` combination is there only for so-called experts to boast over how well they understand python, where list comprehensions are there only because they're easy to understand. – Jean-François Fabre Dec 01 '18 at 14:14
  • 2
    @Jean-FrançoisFabre: agreed, and specifically I'd say that `list+map+lambda` is there to prove that there's something else (probably one or more functional languages) that you're more expert in than you are in Python. – Steve Jessop Dec 01 '18 at 14:15
  • your timings are meaningless, as there are simply two few operations to measure – OrangeDog Dec 01 '18 at 15:44
  • @OrangeDog if the two are generating equivalent machine instructions, they are going to be equivalent in runtime (averaged over n iterations for a sufficiently large n). There just isn't any need to explore this further. Not to say that couldn't change in a different python implementation, but we're drifting into fairly esoteric territory at that point. – Jared Smith Dec 01 '18 at 15:52
  • @Jean-FrançoisFabre not sure how any so-called expert would fail to realize that avoiding the overhead of at least one function call on every iteration of a loop not to mention the instantiation of at least one function object wouldn't result in a huge speed up (or a huge slowdown if looking at it from the opposite direction). That being said, having a common vocabulary with other languages is rarely a bad thing. – Jared Smith Dec 01 '18 at 15:58
  • @OrangeDog but `timeit` runs thousands of times by default. – Jean-François Fabre Dec 01 '18 at 17:55