I’m trying to figure out a fast way to compare the speed of different implementations of a single python algorithm. One option is the timeit module.

I’m not sure the best way to setup these comparisons, so I made a function for each implementation: `divceil1``divceil6`. Then, I made a function to run each and check its output: `test1``test6`. Finally, I’m running the test functions with timeit, e.g.: `timeit.timeit(test6, number=5000)`. The output goes to STDOUT, which I’m redirecting to a CSV file, for processing in a spreadsheet tool. (I know, I know).

Here’s the implementation.

``````#!/usr/bin/python
""" testing various divceil algorithms """
import timeit

def divceil1(numerator, denominator):
""" Returns a division operation rounded up to the next whole number """
# E.G.: 45/20 -> 3 and 40/20 -> 2
quotient, remainder = divmod(numerator, denominator)
return quotient + (1 if remainder > 0 else 0)

def divceil2(numerator, denominator):
""" Returns a division operation rounded up to the next whole number """
# E.G.: 45/20 -> 3 and 40/20 -> 2
quotient, remainder = divmod(numerator, denominator)
return quotient + int(remainder > 0)

def divceil3(numerator, denominator):
""" Returns a division operation rounded up to the next whole number """
# E.G.: 45/20 -> 3 and 40/20 -> 2
quotient, remainder = divmod(numerator, denominator)
return quotient + (remainder > 0)

def divceil4(numerator, denominator):
""" Returns a division operation rounded up to the next whole number """
# E.G.: 45/20 -> 3 and 40/20 -> 2
quotient, remainder = divmod(numerator, denominator)
return quotient + (1 if remainder else 0)

def divceil5(numerator, denominator):
""" Returns a division operation rounded up to the next whole number """
# E.G.: 45/20 -> 3 and 40/20 -> 2
quotient, remainder = divmod(numerator, denominator)
if remainder:
return quotient + 1
return quotient

def divceil6(numerator, denominator):
""" Returns a division operation rounded up to the next whole number """
# E.G.: 45/20 -> 3 and 40/20 -> 2
quotient, remainder = divmod(numerator, denominator)
if remainder:
return quotient + 1
else:
return quotient

def test1():
""" Run divceil1, checking output """
if not (divceil1(45, 20) == 3 and divceil1(40, 20) == 2):
raise ArithmeticError("Something went awry")
return

def test2():
""" Run divceil2, checking output """
if not (divceil2(45, 20) == 3 and divceil2(40, 20) == 2):
raise ArithmeticError("Something went awry")
return

def test3():
""" Run divceil3, checking output """
if not (divceil3(45, 20) == 3 and divceil3(40, 20) == 2):
raise ArithmeticError("Something went awry")
return

def test4():
""" Run divceil4, checking output """
if not (divceil4(45, 20) == 3 and divceil4(40, 20) == 2):
raise ArithmeticError("Something went awry")
return

def test5():
""" Run divceil5, checking output """
if not (divceil5(45, 20) == 3 and divceil5(40, 20) == 2):
raise ArithmeticError("Something went awry")
return

def test6():
""" Run divceil6, checking output """
if not (divceil6(45, 20) == 3 and divceil6(40, 20) == 2):
raise ArithmeticError("Something went awry")
return

REPEAT = 5000
# note ironic use of .format
for _ in xrange(1000):
print "6,{}".format(timeit.timeit(test6, number=REPEAT))
print "5,{}".format(timeit.timeit(test5, number=REPEAT))
print "4,{}".format(timeit.timeit(test4, number=REPEAT))
print "3,{}".format(timeit.timeit(test3, number=REPEAT))
print "2,{}".format(timeit.timeit(test2, number=REPEAT))
print "1,{}".format(timeit.timeit(test1, number=REPEAT))

for _ in xrange(1000):
print "1,{}".format(timeit.timeit(test1, number=REPEAT))
print "2,{}".format(timeit.timeit(test2, number=REPEAT))
print "3,{}".format(timeit.timeit(test3, number=REPEAT))
print "4,{}".format(timeit.timeit(test4, number=REPEAT))
print "5,{}".format(timeit.timeit(test5, number=REPEAT))
print "6,{}".format(timeit.timeit(test6, number=REPEAT))``````

So obviously it would be between divceil5 or divceil6 here. Here are the results:

Algorithm Total Time Average Time
5 19.5343523026 0.0097671762
6 19.7862572670 0.0098931286
4 20.1976833344 0.0100988417
1 20.4852132797 0.0102426066
3 20.5143792629 0.0102571896
2 26.9490272999 0.0134745136

Unsurprisingly, #5 was the fastest.