compare the execution times between two functions in python
# compares the speed of two functions with a single call
# by: codykochmann
import inspect
from timeit import Timer
from operator import itemgetter
import logging
def get_source(func):
""" returns the source code of a function """
return ''.join(inspect.getsourcelines(func)[0])
def time_function(func, iterations=1000000):
""" times a function object a number of iterations and returns the result """
return Timer(get_source(func)+"\n{}()".format(func.__name__)).timeit(iterations)
def sort_by_values(d):
""" sorts a dict by its values and returns it in the form of tuples """
return sorted(d.items(), key=itemgetter(1))
def compare_functions(*args, **kwargs):
""" times two functions and reports which is faster by how much """
# make sure its not a generator
args = tuple(args)
# set up iterations
iterations = kwargs['iterations'] if 'iterations' in kwargs else 1000000
# make sure they have the same output
first_output = args[0]()
for f in args[1:]:
if f() != first_output:
logging.error(' {} does not have the same output'.format(f.__name__))
# time all of them
times = sort_by_values({
f.__name__: time_function(f, iterations) for f in args
})
# print the result
longest_name = max(len(f.__name__) for f in args)
slowest_time = times[-1][1]
print("{0:<6}{1:{2}}{3:<9}{4:<8}".format(
"rank",
"name",
longest_name+2,
"seconds",
"percent"
))
for i in range(len(times)):
print("{0:<6}{1:{2}}{3:<9}{4}%".format(
i+1,
times[i][0],
longest_name+2,
int(times[i][1]*100)/100.0,
int((times[i][1]/slowest_time)*10000)/100.0
))
# ========================
# Example Usage Below
# ========================
def test1():
"Stupid test function"
L = tuple(i for i in range(100))
def test2():
"Stupid test function"
L = list(i for i in range(100))
def test3():
"Stupid test function"
L = set(i for i in range(100))
compare_functions(test1, test2, test3)