eligolf
eligolf

Reputation: 1866

What is the most optimal solution (time wise) for multiple if statements

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

Answers (1)

LMKR
LMKR

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

Related Questions