0

I asked myself if it makes a performance difference if I use an if statement with x conditions, or x if statements with only 1 condition each.

so for example:
if statement with 3 conditions:

if a == 0 and b == 0 and c == 0:
    #do something

3 if statements with just one condition each:

if a == 0:
    if b == 0:
        if c == 0:
            #do something

Why do I want to know this?
I have an if statement with around 30 conditions and my code gets really messi, so I thought about splitting my if-statement in half. I think that the results of this examples will be the same, but I don't know if there would be a noticeable performance difference if a == 1. Would the program check all 3 conditions in the first example even if the first one (a is 1 not 0) is false?

Michael Brown
  • 137
  • 2
  • 13

4 Answers4

1

With the given example, there won't be any difference in performance, even with if a == 0 and b == 0 and c == 0: it won't check b == 0 when the initial condition a == 0 itself is False. But considering the minimal lines of code & readability, if a == 0 and b == 0 and c == 0: would be the better option.

wjandrea
  • 28,235
  • 9
  • 60
  • 81
Maran Sowthri
  • 829
  • 6
  • 14
1

You can test the performance of your script using the timeit library. I will add an example below.

import timeit

stmt1 = 'if a == 0 and b == 0 and c == 0: pass'
stmt2 = """\
if a == 0: 
    if b == 0: 
        if c == 0: 
            pass
"""
setup1 = 'a, b, c = 0, 0, 0'
setup2 = 'a, b, c = 1, 0, 0'

print(f"First statement First setup execution time = {timeit.timeit(stmt=stmt1, setup=setup1, number=10**9)}")
print(f"First statement Second setup execution time = {timeit.timeit(stmt=stmt1, setup=setup2, number=10**9)}")
print(f"Second statement First setup execution time = {timeit.timeit(stmt=stmt2, setup=setup1, number=10**9)}")
print(f"Second statement Second setup execution time = {timeit.timeit(stmt=stmt2, setup=setup2, number=10**9)}")

Output:

First statement First setup execution time = 38.7665075
First statement Second setup execution time = 15.4141367
Second statement First setup execution time = 38.29726529999999
Second statement Second setup execution time = 15.527892699999995

This shows that there is negligible difference to how you format your if statement. But if the first condition is false then the rest of the conditions will not be checked and the execution of the code will run faster.

Edit:

Also after seeing wjandrea comment below I would like to add it to the answer if anyone in the future is wondering why this is. Per the python wiki you can read about short-circuiting operator behavior.

Oddity
  • 480
  • 2
  • 12
  • Nice! To make it even better, move the assignments into a setup statement. Also fwiw I prefer to write big numbers as exponents for readability. For example, `flat = 'if a == 0 and b == 0 and c == 0: pass'; a_0 = 'a, b, c = 0, 0, 0'; ... timeit.timeit(stmt=flat, setup=a_0, number=10**9)` – wjandrea Oct 03 '20 at 06:56
  • @wjandrea Thanks for the info. I left in the second statement with the multiline if to show that it makes no difference other than making your code messier. Also I see that the execution times where reduced, I am guessing because prior to using setup I was defining the variables each run, but now they are only defined once? – Oddity Oct 03 '20 at 07:06
  • Yes, exactly, now they're only defined once. – wjandrea Oct 03 '20 at 07:11
  • Are you sure those times are right? They're like x8 what they were before. – wjandrea Oct 03 '20 at 07:12
  • @wjandrea I changed it from 100million to 1billion executions per your 10**9 instead of using 10**8 to keep it the same. It didn't take it that long and I feel like the larger the dataset the better right? – Oddity Oct 03 '20 at 07:17
  • Oh, I see what happened: you wrote 1 billion by accident and I forgot to count the zeroes, just did the math. Yeah, the larger the better to an extent. I think even 10 million would be fine for this. – wjandrea Oct 03 '20 at 07:50
  • @wjandrea thanks for the information and everything I just used timeit to answer my own question! https://stackoverflow.com/questions/64180375/python-c-sharp-datatypes-for-sockets/64181985#64181985 – Oddity Oct 03 '20 at 07:58
0

Any time difference between your two pieces of code is complete and total noise. Run your code a billion times, and the amount of time you might save between running one or the other is less than the time it took me to write these two sentences.

Seriously, if you need to be worried about the difference in time between the two pieces of code, Python is the wrong language.

Frank Yellin
  • 9,127
  • 1
  • 12
  • 22
  • *"Any time difference between your two pieces of code is complete and total noise."* Why is that? Please explain for OP's sake. You might want to mention operator short-circuiting. – wjandrea Oct 03 '20 at 06:28
0

Yes! I think there is an increase of productivity/performance if you can write your code in one line, since often times it can be easier to read and interpret; and even more so if you use descriptive variables.

In your code, I see some things that can be improved: There is what we call the (1) assignment operator, i.e. the equal(=) sign; and (2) The comparison operator, i.e. the "is equal to" (==) sign, "is greater than" (>), "is less than" (<), and etc.

When we define a variable, we use the assignment operator (=) sign. e.g:

a = 0
b = 0
c = 0

On the other hand, we use the comparison operator (such as the (==) symbol) when we make conditional statements. e.g:

if a == 0 and b == 0 and c == 0:
    # do something

On to your second question: Would the program check all 3 conditions in the first example even if the first one (a is 1 not 0) is false?

a = 1
b = 0
c = 0

if a == 0:
    if b == 0:
        if c == 0:
            # do something

Python will compare the conditions to your assigned variables, and if the condition turns out to be False, then there will be no ERROR, but it will also not execute the instruction that you've provided in your if-statement (meaning: it will not # do something).

I hope I had help you even a little bit.

Lucky
  • 129
  • 3
  • 11