我正在学习如何在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/

10-13 02:28