我正在学习如何在IPython中使用%timeit
magic命令,实际上是结合使用Jupyter Notebook和Python 3。
n = 10
for i in range(n):
arr = np.random.rand(2**(i+10))
%timeit -n 2 np.sort(arr)
然后,我得到了一系列大致增加的时间,就像我期望的那样。
但是,如果我尝试将此代码打包到一个函数中,则不会得到我期望的输出:所有时间都差不多!
def my_func(n):
for i in range(n):
arr = np.random.rand(2**(i+10))
%timeit -n 10 np.sort(arr)
my_func(10)
请查看Jupyter笔记本,显示结果here。
谁能解释我做错了什么,或者我误解了什么?
最佳答案
%timeit
不应在函数内部正常运行(当前)。如果您启动一本新笔记本(或重新启动您的笔记本)并且仅使用:
import numpy as np
def my_func(n):
for i in range(n):
arr = np.random.rand(2**(i+10))
%timeit -n 10 np.sort(arr)
my_func(10)
它将抛出一个
NameError
:NameError:未定义名称“ arr”
这是因为
%timeit
仅检查全局变量,而不检查局部变量(因此它将忽略函数内部定义的变量arr = np.random.rand(2**(i+10))
)。如果使用此代码,将很明显:
import numpy as np
arr = np.array([1, 2, 3])
def my_func(n):
for i in range(n):
arr = np.random.rand(2**(i+10))
%timeit -n 2 -r 1 print(arr)
my_func(10)
打印:
[1 2 3]
[1 2 3]
每个循环3.44 ms±0 ns(平均±标准偏差,运行1次,每个循环2个)
[1 2 3]
[1 2 3]
每个回路670 µs±0 ns(平均±标准偏差,运行1次,每个回路2个)
[1 2 3]
[1 2 3]
每个循环2.04 ms±0 ns(平均±标准偏差,运行1次,每个循环2个)
[1 2 3]
[1 2 3]
每个回路451 µs±0 ns(平均±标准偏差,运行1次,每个回路2个)
[1 2 3]
[1 2 3]
每个回路906 µs±0 ns(平均±标准偏差,运行1次,每个回路2个)
[1 2 3]
[1 2 3]
每个循环1.01 ms±0 ns(平均±标准偏差。运行1次,每个2个循环)
[1 2 3]
[1 2 3]
每个循环767 µs±0 ns(平均±标准偏差,运行1次,每个循环2个)
[1 2 3]
[1 2 3]
每个回路890 µs±0 ns(平均±标准偏差,运行1次,每个回路2个)
[1 2 3]
[1 2 3]
每个循环1.28 ms±0 ns(平均±标准偏差。运行1次,每个2个循环)
[1 2 3]
[1 2 3]
每个回路919 µs±0 ns(平均±标准偏差,运行1次,每个回路2个)
因此,在您的情况下,它始终会在非功能运行(全局)中找到最后一个
arr
。这也解释了为什么该功能的时间大致相同。因为它总是找到相同的arr
。关于python - 当我使用IPython/Jupyter将“%timeit”放入函数中时,为什么会得到不好的计时结果?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/46025715/