Not a maths major or a cs major, I just fool around with python (usually making scripts for simulations/theorycrafting on video games) and I discovered just how bad random.randint is performance wise. It's got me wondering why random.randint or random.randrange are used/made the way they are. I made a function that produces (for all intents and actual purposes) identical results to random.randint:
big_bleeping_float= (2**64 - 2)/(2**64 - 2) def fastrandint(start, stop): return start + int(random.random() * (stop - start + big_bleeping_float)) There is a massive 180% speed boost using that to generate an integer in the range (inclusive) 0-65 compared to random.randrange(0, 66), the next fastest method.
>>> timeit.timeit('random.randint(0, 66)', setup='from numpy import random', number=10000) 0.03165552873121058 >>> timeit.timeit('random.randint(0, 65)', setup='import random', number=10000) 0.022374771118336412 >>> timeit.timeit('random.randrange(0, 66)', setup='import random', number=10000) 0.01937231027605435 >>> timeit.timeit('fastrandint(0, 65)', setup='import random; from fasterthanrandomrandom import fastrandint', number=10000) 0.0067909916844523755 Furthermore, the adaptation of this function as an alternative to random.choice is 75% faster, and I'm sure adding larger-than-one stepped ranges would be faster (although I didn't test that). For almost double the speed boost as using the fastrandint function you can simply write it inline:
>>> timeit.timeit('int(random.random() * (65 + big_bleeping_float))', setup='import random; big_bleeping_float= (2**64 - 2)/(2**64 - 2)', number=10000) 0.0037642723021917845 So in summary, why am I wrong that my function is a better, why is it faster if it is better, and is there a yet even faster way to do what I'm doing?
random()*Ngenerates values from(0,N]and applying int to this rounds down, giving ints in (0,N-1)big_bleeping_float- just that it is actually required for the values to be correct.