2016-02-12 166 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=参数在每次迭代中生成一个新的随机列表。