Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using magic command %% timeit -n1 -r1 causes jupyter does not keep the value of local variables

I just noticed to something very strange. When I use %%timeit -n1 -r1 magic command, to measure the execution time of a block of code in Jupyter lab, python does not keep the value of local variables after the execution of the block! For instance, if I run a block of code containing the following codes:

for i in range(10):
   for j in range(10):
       d = i - j

and then run print(d) in another block, the jupyter will show me the value of d in the last iteration. But if I run this block of code:

%%timeit -n1 -r1
for in in range(10):
   for j in range(10):
       d = i - j

and then run print(d), the juoyter shows me an error message:

NameError: name 'd' is not defined

What is the explanation behind this strange behaviour?

like image 333
amiref Avatar asked Nov 06 '22 20:11

amiref


1 Answers

IPython/Jupyter takes the block of code in the cell and runs it in a function whose scope is not visible to your __main__ module's namespace. Judging from this answer, it seems to take the cell as a string:

In [4]: get_ipython().magic('timeit 1 + 2')                                                                                                                                                                        
11.2 ns ± 0.167 ns per loop (mean ± std. dev. of 7 runs, 100000000 loops each)

In [5]: %%timeit 
   ...: 1 + 2 
   ...:  
   ...:                                                                                                                                                                                                            
11.1 ns ± 0.17 ns per loop (mean ± std. dev. of 7 runs, 100000000 loops each)

The variables from the loop are known to whatever IPython function runs and times the loop, but not accessible outside of that Timer instance method.

When you run the for i in range(10) loop (without %%timeit) in a cell (or just in a plain-vanilla Python interactive interpreter), the way that Python handles a for-loop is to dynamically re-assign the i, j, and d values in each iteration of the loop. They will still be sitting around in the namespace of __main__ (this is the __name__ dunder attribute in a Python shell) after the loop has run its course.

like image 53
Brad Solomon Avatar answered Nov 14 '22 22:11

Brad Solomon