选择的性能与 randint
Performance of choice vs randint
我想在 a
和 b
之间随机选择一个整数(含)。
我知道 3 种方法。然而,他们的表现似乎很反直觉:
import timeit
t1 = timeit.timeit("n=random.randint(0, 2)", setup="import random", number=100000)
t2 = timeit.timeit("n=random.choice([0, 1, 2])", setup="import random", number=100000)
t3 = timeit.timeit("n=random.choice(ar)", setup="import random; ar = [0, 1, 2]", number=100000)
[print(t) for t in [t1, t2, t3]]
在我的机器上,这给出:
0.29744589625620965
0.19716156798482648
0.17500512311108346
使用 online interpreter,得到:
0.23830216699570883
0.16536146598809864
0.15081614299560897
请注意,使用专用函数来完成我正在做的事情的最直接版本 (#1) 比最奇怪的版本 (#3) 差 50%预先定义一个数组,然后从中随机选择。
怎么回事?
这只是实现细节。 randint
delegates to randrange
, so it has another layer of function call overhead, and randrange
goes through a lot of argument checking and other crud. In contrast, choice
是一个非常简单的单行代码。
这是此调用所经过的代码路径 randint
,删除了注释和未执行的代码:
def randint(self, a, b):
return self.randrange(a, b+1)
def randrange(self, start, stop=None, step=1, _int=int, _maxwidth=1L<<BPF):
istart = _int(start)
if istart != start:
# not executed
if stop is None:
# not executed
istop = _int(stop)
if istop != stop:
# not executed
width = istop - istart
if step == 1 and width > 0:
if width >= _maxwidth:
# not executed
return _int(istart + _int(self.random()*width))
这里是 choice
经过的代码路径:
def choice(self, seq):
return seq[int(self.random() * len(seq))]
我想在 a
和 b
之间随机选择一个整数(含)。
我知道 3 种方法。然而,他们的表现似乎很反直觉:
import timeit
t1 = timeit.timeit("n=random.randint(0, 2)", setup="import random", number=100000)
t2 = timeit.timeit("n=random.choice([0, 1, 2])", setup="import random", number=100000)
t3 = timeit.timeit("n=random.choice(ar)", setup="import random; ar = [0, 1, 2]", number=100000)
[print(t) for t in [t1, t2, t3]]
在我的机器上,这给出:
0.29744589625620965
0.19716156798482648
0.17500512311108346
使用 online interpreter,得到:
0.23830216699570883
0.16536146598809864
0.15081614299560897
请注意,使用专用函数来完成我正在做的事情的最直接版本 (#1) 比最奇怪的版本 (#3) 差 50%预先定义一个数组,然后从中随机选择。
怎么回事?
这只是实现细节。 randint
delegates to randrange
, so it has another layer of function call overhead, and randrange
goes through a lot of argument checking and other crud. In contrast, choice
是一个非常简单的单行代码。
这是此调用所经过的代码路径 randint
,删除了注释和未执行的代码:
def randint(self, a, b):
return self.randrange(a, b+1)
def randrange(self, start, stop=None, step=1, _int=int, _maxwidth=1L<<BPF):
istart = _int(start)
if istart != start:
# not executed
if stop is None:
# not executed
istop = _int(stop)
if istop != stop:
# not executed
width = istop - istart
if step == 1 and width > 0:
if width >= _maxwidth:
# not executed
return _int(istart + _int(self.random()*width))
这里是 choice
经过的代码路径:
def choice(self, seq):
return seq[int(self.random() * len(seq))]