@PGriffith showed me a python decorator script on another thread, which gave me an idea on how to use it for timing module functions. I’m sure someone else has done this and maybe better, but it has been fun to play with.
The decorator takes two arguments which determine the time units to be returned and how many times the function should be called.
import functools
from java.lang import System
class benchmark(object):
''' decorator for benchmarking scripts'''
def __init__(self,units,n):
if units == 'seconds':
divisor = 100000000.0
elif units == 'nanos':
divisor = 1.0
else:
units = 'millis'
divisor = 100000.0
self.n = n
self.divisor = divisor
self.fmt = '{:d} calls of {:s}, avg: {:.1f} %s' % units
def __call__(self,fn):
# returns the decorator itself, which accepts a function and returns another function
# wraps ensures that the name and docstring of 'fn' is preserved in 'wrapper'
@functools.wraps(fn)
def wrapper(*args, **kwargs):
# the wrapper passes all parameters to the function being decorated
t1 = System.nanoTime()
for _ in range(self.n):
res = fn(*args, **kwargs)
t2 = System.nanoTime()
total = (t2-t1)/self.divisor/self.n
print(self.fmt.format(self.n, fn.__name__, total))
return res
return wrapper
@benchmark("millis", 10)
def sayHello(a1, a2, a3, a4):
print 'sayHello arguments:', a1, a2, a3, a4
sayHello(1,2,3,4)
output
sayHello arguments: 1 2 3 4
sayHello arguments: 1 2 3 4
sayHello arguments: 1 2 3 4
sayHello arguments: 1 2 3 4
sayHello arguments: 1 2 3 4
sayHello arguments: 1 2 3 4
sayHello arguments: 1 2 3 4
sayHello arguments: 1 2 3 4
sayHello arguments: 1 2 3 4
sayHello arguments: 1 2 3 4
10 calls of sayHello, avg: 3.1 millis