选择绩效vs randint [英] Performance of choice vs randint

查看:155
本文介绍了选择绩效vs randint的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想选择一个介于ab之间的随机整数.

I want to pick a random integer between a and b, inclusive.

我知道3种方式.但是,它们的表现似乎非常违反直觉:

I know 3 ways of doing it. However, their performance seems very counter-intuitive:

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]]

在我的机器上,这给出了:

On my machine, this gives:

0.29744589625620965
0.19716156798482648
0.17500512311108346

使用在线解释器,它可以:

0.23830216699570883
0.16536146598809864
0.15081614299560897

请注意,使用专用功能完成我正在做的事情的最直接版本(#1)比预定义数组的最奇怪的版本(#3)差50%(em)50%.然后从中随机选择.

Note how the most direct version (#1) that uses the dedicated function for doing what I'm doing is 50% worse that the strangest version (#3) which pre-defines an array and then chooses randomly from it.

这是怎么回事?

推荐答案

这只是实现细节. randint 代表 choice 是一个非常简单的-内衬.

It's just implementation details. 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 is a really simple one-liner.

这是此调用的代码路径randint,其中注释和未执行的代码被删除:

Here's the code path randint goes through for this call, with comments and unexecuted code stripped out:

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))]

这篇关于选择绩效vs randint的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆