I have read several thread in Stackoverflow. Many claim that using a dict is faster than if-elif-else statements in Python. I made some test using Python 3.7.4 and got different results.
I have built a test script. I used timeit to measure my code. I'm building an interpreter of pseudocode. My interpreter uses if-elif-else statements to find the python procedure to interpret an specific pseudocode. But I wanted to move to a dict approve and made some testing.
from timeit import Timer
def add(x, y):
return x + y
def sub(x, y):
return x - y
def mul(x, y):
return x * y
def div(x, y):
return x / y
def foo1(oper, a, b):
return funcs[oper](a, b)
def foo2(oper, a, b):
if oper == 'add':
return a + b
elif oper == 'sub':
return a - b
elif oper == 'mul':
return a * b
else:
return a / b
def foo3(oper, a, b):
subfuncs[oper](a, b)
funcs = {'add': lambda x, y: x + y,
'sub': lambda x, y: x - y,
'mul': lambda x, y: x * y,
'div': lambda x, y: x / y}
subfuncs = {'add': add,
'sub': sub,
'mul': mul,
'div': div}
times_to_run = 10000000
t1 = Timer("foo1('div', 3, 2)", "from __main__ import foo1")
t2 = Timer("foo2('div', 3, 2)", "from __main__ import foo2")
t3 = Timer("foo3('div', 3, 2)", "from __main__ import foo3")
tot1 = t1.timeit(times_to_run)
tot2 = t2.timeit(times_to_run)
tot3 = t3.timeit(times_to_run)
print("Time for foo1 is: {:4.2f}".format(tot1))
print("Time for foo2 is: {:4.2f}".format(tot2))
print("Time for foo3 is: {:4.2f}".format(tot3))
if tot1 > tot2:
res1 = 'slower'
times1 = '{:6.2f}'.format((tot1 / tot2 - 1) * 100)
elif tot1 < tot2:
res1 = 'faster'
times1 = '{:6.2f}'.format((tot2 / tot1 - 1) * 100)
else:
res1 = 'equal'
times1 = ''
print("\nfoo1 is {}% {} in comparison to foo2".format(times1, res1))
if tot2 > tot3:
res2 = 'slower'
times2 = '{:6.2f}'.format((tot2 / tot3 - 1) * 100)
elif tot2 < tot3:
res2 = 'faster'
times2 = '{:6.2f}'.format((tot3 / tot2 - 1) * 100)
else:
res2 = 'equal'
times2 = ''
print("foo2 is {}% {} in comparison to foo3".format(times2, res2))
if tot1 > tot3:
res3 = 'slower'
times3 = '{:6.2f}'.format((tot1 / tot3 - 1) * 100)
elif tot1 < tot3:
res3 = 'faster'
times3 = '{:6.2f}'.format((tot3 / tot1 - 1) * 100)
else:
res3 = 'equal'
times3 = ''
print("foo1 is {}% {} in comparison to foo3".format(times3, res3))
I was expecting that foo3 would be the fastest function, instead foo2 is the fastest every time. I always get output similar to this, and outputs are always consistence to this output:
Time for foo1 is: 3.35
Time for foo2 is: 2.99
Time for foo3 is: 3.06
foo1 is 12.18% slower in comparison to foo2
foo2 is 2.51% faster in comparison to foo3
foo1 is 9.44% slower in comparison to foo3
My question is why foo2, which has if-elif-else statements is faster than using foo3 which uses a dict of functions?
PS. This is not my actual code. I'm testing which approach would be faster.