为什么 random.shuffle 比使用 sorted 函数慢这么多?

maz*_*ore 5 python random performance shuffle

使用 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))
Run Code Online (Sandbox Code Playgroud)

Sha*_*ger 4

On CPython(参考解释器)random.shuffle是在 Python 中实现的(并根据 来实现_randbelow,它本身是一个 Python 包装器getrandbits,最终实现它的 C 级函数,并且最终可以被调用的频率几乎是严格必要的两倍确保输出没有偏见);sorted( 和random.random) 是用 C 实现的。在 Python 中执行工作的开销高于在 C 中执行类似工作的开销。

  • @Evan:它使用了相当艰苦的算法来保证(在 PRNG 的限制下)完美的洗牌;避免偏见是一个令人惊讶的难题,与确保其绝对正确相比,使其更快更重要。“random”模块中存在许多错误,导致输出出现轻微偏差(这就是为什么“_randbelow”以现在的方式实现),并且他们通常非常热衷于使用更快的算法,而这些算法并不是“事实证明是公正的。 (3认同)