2017-09-03 84 views
1

我正在學習如何在IPython中使用%timeit魔法命令,實際使用Jupyter筆記本與Python 3,如果我嘗試替不同大小的數組的NumPy的排序功能:當我在IPython/Jupyter的函數中加入「%timeit」時,爲什麼我的計時結果不好?

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

任何人都可以解釋我做錯了什麼,或者我誤解了什麼?

+0

'%timeit'是Jupyter支持的特殊語法,它並不是真正有效的Python代碼。所以我期望Jupyter分開解析它,並且它對整個執行的命令有影響。直接嘗試使用'timeit'模塊。 – poke

+0

在第二種情況下,您只是反覆排序在第一個單元格中創建的全局'arr',而不是本地arr。將局部變量名稱更改爲其他名稱,您將看到%timeit抱怨什麼。 – pvg

回答

1

%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: name 'arr' is not defined

這是因爲%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 per loop (mean ± std. dev. of 1 run, 2 loops each) 
[1 2 3] 
[1 2 3] 
670 µs ± 0 ns per loop (mean ± std. dev. of 1 run, 2 loops each) 
[1 2 3] 
[1 2 3] 
2.04 ms ± 0 ns per loop (mean ± std. dev. of 1 run, 2 loops each) 
[1 2 3] 
[1 2 3] 
451 µs ± 0 ns per loop (mean ± std. dev. of 1 run, 2 loops each) 
[1 2 3] 
[1 2 3] 
906 µs ± 0 ns per loop (mean ± std. dev. of 1 run, 2 loops each) 
[1 2 3] 
[1 2 3] 
1.01 ms ± 0 ns per loop (mean ± std. dev. of 1 run, 2 loops each) 
[1 2 3] 
[1 2 3] 
767 µs ± 0 ns per loop (mean ± std. dev. of 1 run, 2 loops each) 
[1 2 3] 
[1 2 3] 
890 µs ± 0 ns per loop (mean ± std. dev. of 1 run, 2 loops each) 
[1 2 3] 
[1 2 3] 
1.28 ms ± 0 ns per loop (mean ± std. dev. of 1 run, 2 loops each) 
[1 2 3] 
[1 2 3] 
919 µs ± 0 ns per loop (mean ± std. dev. of 1 run, 2 loops each) 

所以你的情況總是發現從非功能運行的最後arr(這是全球)。這也解釋了爲什麼該功能的時間大致相同。因爲它總是發現相同arr

相關問題