2016-02-12 22 views
2

嘗試使用不同的隨機函數來查看從列表中選擇隨機項的最快方法。 %timeit想給我「最好的3」的最快時間,但由於運行是隨機的,訪問時間差異很大(從列表後面抓取,速度會很慢;從前面抓取,會很快)。從'%timeit`獲得平均運行時間ipython magic

如何獲得所有循環的平均值,而不是最好的?

a = [0,6,3,1,3,9,4,3,2,6] 

%timeit random.choice(a) 
%timeit a[random.randint(0,len(a)-1)] 
%timeit a[np.random.randint(0,len(a)-1)] 
%timeit np.random.choice(a,1)[0] 

目前輸出(承認方差時間):

%timeit random.choice(a) 
The slowest run took 9.87 times longer than the fastest. This could mean that an intermediate result is being cached 
1000000 loops, best of 3: 1.23 µs per loop 

更新:一個雜牌的方法:

%time for i in range(100000): random.choice(a) 
%time for i in range(100000): a[random.randint(0,len(a)-1)] 
%time for i in range(100000): a[np.random.randint(0,len(a)-1)] 
%time for i in range(100000): np.random.choice(a,1)[0] 
+0

「嘗試計時不同的隨機函數以查看從列表中選擇隨機項目的最快方式。」 - 這種(可能)搶先微優化將無處可用。 – kay

+0

@Kay我模擬了數千萬個節點的網絡上的隨機行走。我保證 - 即使很小的差異也會影響很大。目前,隨機抽籤是我運行時間的60%。 (不,這不是先發制人 - 我瘋狂地描繪) –

+1

你是否嘗試過從numpy數組而不是列表繪製?我認爲'np.random.choice'將'a'轉換爲一個數組,這可能相當昂貴。我看到了len(10)列表與數組之間6倍差異的因素。 –

回答

0

有多快

random_fd = open('/dev/urandom', 'rb') 

a = array.array('I') 
a.read(random_fd, 10**8) 

get_next_rand = iter(a).next 

適合你?如果這是您的瓶頸,我只會一次生成大量的隨機數。

在我的年齡PC:

%timeit array.array('I').read(open('/dev/urandom', 'rb'), 10**6) 
1 loop, best of 3: 200 ms per loop 
+0

這是個好主意。之後我需要對它們進行調整 - 我從每個樣本中抽取的樣本長度不同 - 但是從0-1生成隨機數字,長度爲多個並循環爲整數可能仍然更有效。謝謝! –

+1

不客氣!只要確保不要在使用modulo時引入偏見:http://stackoverflow.com/q/10984974/416224 – kay

1

你可以使用timeit.repeat

import timeit 
import numpy as np 

reps = timeit.repeat(repeat=3, n=10000, 
        stmt="np.random.choice(a)", 
        setup="import numpy as np; a=[0,6,3,1,3,9,4,3,2,6]") 

# taking the median might be better, since I suspect the distribution of times will 
# be heavily skewed 
avg = np.mean(reps) 

一個潛在的問題是,你有可能碰到的緩存作用,可以使您的時間意義不大(see here)。例如,您可能想使用setup=參數在每次迭代中生成一個新的隨機列表。