Reputation: 1866
The examples below are from my chess game but the question is more general for runtime optimizing if-statements in Python. What type of code will run faster, and is there a huge difference? Bare in mind that in this case I will calculated this inside a minimax algorithm (thousands of times). Case 3 if of course nicer, but is it faster to run?
Another question would be if there is a difference in the order of which I put these values in? In this case the pawn option will come up the most times, is it then better to have that one first in the if-statements/dict?
# Case 1:
if piece_type == 'K':
value = 20000
elif piece_type == 'Q':
value = 900
elif piece_type == 'B':
value = 330
elif piece_type == 'N':
value = 320
elif piece_type == 'R':
value = 500
elif piece_type == 'p':
value = 100
return value
# Case 2:
if piece_type == 'K':
return 20000
elif piece_type == 'Q':
return 900
elif piece_type == 'B':
return 330
elif piece_type == 'N':
return 320
elif piece_type == 'R':
return 500
elif piece_type == 'p':
return 100
# Case 3:
piece_values = {'K': 20000, 'Q': 900, 'B': 330, 'N': 320, 'R': 500, 'p': 100}
return piece_values.get('K')
Upvotes: 0
Views: 54
Reputation: 647
import timeit
piece_type = 'p'
def case1():
if piece_type == 'K':
value = 20000
elif piece_type == 'Q':
value = 900
elif piece_type == 'B':
value = 330
elif piece_type == 'N':
value = 320
elif piece_type == 'R':
value = 500
elif piece_type == 'p':
value = 100
return value
def case2():
if piece_type == 'K':
return 20000
elif piece_type == 'Q':
return 900
elif piece_type == 'B':
return 330
elif piece_type == 'N':
return 320
elif piece_type == 'R':
return 500
elif piece_type == 'p':
return 100
piece_values = {'K': 20000, 'Q': 900, 'B': 330, 'N': 320, 'R': 500, 'p': 100}
def case3():
return piece_values.get(piece_type)
N = 1000
r1 = 0
r2 = 0
r3 = 0
for i in range(N):
r1 += timeit.timeit("case1()", setup="from __main__ import case1", number=100000)
r2 += timeit.timeit("case2()", setup="from __main__ import case2", number=100000)
r3 += timeit.timeit("case3()", setup="from __main__ import case3", number=100000)
print(r1/N)
print(r2/N)
print(r3/N)
Results
For piece_type = 'p'
0.043659273699999786
0.042489134299999745
0.025282950800000023
For peice_type = 'K'
0.017085672599999883
0.015899844999999937
0.02493290909999991
As if we see the results, accessing elements of dictionary doesn't matter where the element is located.
Accessing elements down the if-else ladder cost more time compared to the elements at the top of ladder.
So if the conditionals are less then if-else is better, if there are large number of conditionals then dictionary is better as dictionary is always O(1).
Upvotes: 1