Functions that return random number are many times the computational bottlenecks of my programs. On top of that, I like to write generic but sometimes the result is that I call a random function that has a trivial domain, that is, there is only one value it can even possible return. I wondered if NumPy knows how to handle that, but it turns out it doesn't. I'll show you.
First I define a function that returns a discrete uniform number between 0 and n:
from numpy.random import random_integers
from timeit import timeit
def uniform(n):
return random_integers(0,n)
Next I define a smart function that returns discrete uniform, but first checks that the domain is not trivial, an dif it is, it returns the trivial value:
def smart_uniform(n):
if n==0:
return 0
else:
return random_integers(0,n)
def trivial():
return 0
Now I define a factory function that for a given function (which will be either uniform or smart_uniform) returns two versions - one with a range limit 0 and one with a range limit 1, both given as the first argument. This is used by the timeit function timer later on.
def function_factory(func):
def f0():
return func(0)
def f1():
return func(1)
return f0,f1
uniform0,uniform1 = function_factory(uniform)
smart_uniform0,smart_uniform1 = function_factory(smart_uniform)
Now I use the timeit function timer to time how long each function calls takes. timeit is nice, it calls the function many times and calculates the average time. But as far as I know it doesn't take arguments, which is why I needed the above function factory.
As you can see, the uniform functions take roughly the same time, although uniform 0 is trivial and always returns 0. The smart function for the trivial case does take less time than the regular version - because it doesn't do the random draws - but still takes longer than the trivial version, probably because of the if calls.
The bad news are that the non-trivial smart uniform function takes much longer than the regular version, which means this is not a good implementation.
print "trivial 0:",timeit(trivial)
print "uniform 0:",timeit(uniform0)
print "uniform 1:",timeit(uniform1)
print "smart uniform 0:",timeit(smart_uniform0)
print "smart uniform 1:",timeit(smart_uniform1)
trivial 0: 0.380914433709 uniform 0: 1.632382798 uniform 1: 1.66399043729 smart uniform 0: 1.00784697256 smart uniform 1: 2.23995387685