CodyKochmann
1/25/2017 - 2:36 PM

compare the execution times between two functions in python

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)