【发布时间】:2019-09-26 20:54:06
【问题描述】:
我对一些随机整数生成代码的相对速度感到好奇。我写了以下内容来检查一下:
from random import random
from random import choice
from random import randint
from math import floor
import time
def main():
times = 1000000
startTime = time.time()
for i in range(times):
randint(0,9)
print(time.time()-startTime)
startTime = time.time()
for i in range(times):
choice([0,1,2,3,4,5,6,7,8,9])
print(time.time()-startTime)
startTime = time.time()
for i in range(times):
floor(10*random())##generates random integers in the same range as randint(0,9)
print(time.time()-startTime)
main()
这段代码的一次试验结果是
0.9340872764587402
0.6552846431732178
0.23188304901123047
即使在执行了乘法和 math.floor 之后,生成整数的最终方法也是迄今为止最快的。弄乱生成数字的范围大小并没有改变任何东西。
那么,为什么 random 方式比 randint 快?是否有任何理由(除了易用性、可读性和不引起错误)人们更喜欢 randint 而不是随机(例如,randint 产生更多随机伪随机整数)?如果floor(x*random()) 感觉可读性不够,但您想要更快的代码,您是否应该使用专门的例程?
def myrandint(low,high): ###still about 1.6 longer than the above, but almost 2.5 times faster than random.randint
return floor((high-low+1)*random())+low ##returns a random integer between low and high, inclusive. Results may not be what you expect if int(low) != low, etc. But the numpty who writes 'randint(1.9,3.2)' gets what they deserve.
【问题讨论】:
-
randint 在底层使用
randrange,它有一个带有大量开销的python 实现:github.com/python/cpython/blob/master/Lib/random.py#L211 基本上在每次调用该函数时,它都会进行大量错误检查。如果你不需要这些,你当然可以使用更简单的实现。 -
使用
floor(n*random())计算[0, n)中的整数存在偏差。对于n=10,这种偏差在统计上是无法检测到的,但对于较大的n,可能会出现问题。例如,请参阅 bugs.python.org/issue9025 进行一些讨论。