Rendimiento de elección vs randint

Quiero elegir un entero aleatorio entre a y b , inclusive.

Conozco 3 formas de hacerlo. Sin embargo, su rendimiento parece muy contraintuitivo:

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

En mi máquina, esto da:

 0.29744589625620965 0.19716156798482648 0.17500512311108346 

Usando un intérprete en línea , esto da:

 0.23830216699570883 0.16536146598809864 0.15081614299560897 

Tenga en cuenta que la versión más directa (# 1) que usa la función dedicada para hacer lo que estoy haciendo es un 50% peor que la versión más extraña (# 3) que predefinida una matriz y luego la elige aleatoriamente.

¿Que esta pasando?

Solo son detalles de la implementación. randint delega a randrange , por lo que tiene otra capa de sobrecarga de llamadas a funciones, y randrange pasa por una gran cantidad de verificación de argumentos y otros problemas. Por el contrario, la choice es realmente una línea simple.

Aquí está la ruta del código por la que pasa randint para esta llamada, con comentarios y código no ejecutado eliminado:

 def randint(self, a, b): return self.randrange(a, b+1) def randrange(self, start, stop=None, step=1, _int=int, _maxwidth=1L< 0: if width >= _maxwidth: # not executed return _int(istart + _int(self.random()*width)) 

Y aquí está la choice camino del código que pasa por:

 def choice(self, seq): return seq[int(self.random() * len(seq))]