使用pythonsrandom.shuffle
函数时,我注意到它的使用速度明显快sorted(l, key=lambda _: random.random())
于random.shuffle(l)
。据我了解,这两种方式都会产生完全随机的列表,那么为什么shuffle
要花这么长的时间呢?
以下是使用timeit
模块的时间。
from timeit import timeit
setup = 'import random\nl = list(range(1000))'
# 5.542 seconds
print(timeit('random.shuffle(l)', setup=setup, number=10000))
# 1.878 seconds
print(timeit('sorted(l, key=lambda _: random.random())', setup=setup, number=10000))
在CPython上(参考解释器)random.shuffle
是在Python中实现的(其实现_randbelow
本身就是一个Python包装器getrandbits
,最终实现了它的C级函数,最终被调用的频率几乎是严格需要的两倍)确保输出没有偏见);sorted
(和random.random
)在C中实现。在Python中执行工作的开销比在C中执行类似的工作要高。
如果使用C运行得这么快,为什么
random.shuffle
不只返回列表sorted
呢?@Evan:它使用了相当艰苦的算法,可以保证(在PRNG的范围内)完美的改组;避免偏见是一个非常棘手的难题,要使其更快变得比确保其正确性要紧。该
random
模块中存在许多错误,这些错误导致输出略有偏差(这就是为什么_randbelow
要按现在的方式实现),并且对于使用无法证明无偏的更快算法,他们通常是很熟练的。