Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is lambda function execution time different when passed as callable vs being passed as a string statement to timeit.repeat()?

Tags:

python

timeit

I got different results of the following two python timeit lines.

print(min(timeit.repeat(lambda: 1+1)))
print(min(timeit.repeat('lambda: 1+1')))

The output is something like:

0.13658121100002063
0.10372773000017332

Could you pls help explain the difference between them?

like image 232
Penguin Bear Avatar asked Jan 30 '23 11:01

Penguin Bear


1 Answers

On second sight, this is a really interesting question!

But first, please have another look at the docs:

The constructor takes a statement to be timed, an additional statement used for setup, and a timer function. Both statements default to 'pass'; the timer function is platform-dependent (see the module doc string). [...]

The stmt and setup parameters can also take objects that are callable without arguments. This will embed calls to them in a timer function that will then be executed by timeit(). Note that the timing overhead is a little larger in this case because of the extra function calls.

When you manage to not fall for the trap to attribute the observed difference to the function call overhead, you notice: the first argument is either a callable that is called or a statement that is executed.

So, in your two lines of code you measure the performance of two different things.

In the first line you pass a callable that is being called and its execution time is measured:

timeit.repeat(lambda: 1+1)

Here you pass a statement that is being executed and its execution time is measured:

timeit.repeat('lambda: 1+1')

Note that in the second case you don't actually call the function, but measure the time it takes to create the lambda!

If you again wanted to measure the execution time of the function call, you should have written something like this:

timeit.repeat('test()', 'test=lambda: 1+1')

For comparison, look at this example:

import time
print(min(timeit.repeat(lambda: time.sleep(1), number=1))) 
print(min(timeit.repeat('lambda: time.sleep(1)', number=1))) 

The output clearly shows the difference (first calls function, second creates function):

1.0009081270000024
5.370002327254042e-07
like image 141
moooeeeep Avatar answered Feb 14 '23 18:02

moooeeeep