Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

While-loop with if-statement faster than while-loop

I am doing some testing regarding the speed of if-statements in loops and their effect on speed. Something I found was that consistently, the if-statement improved performance. My code:

import time
t = time.time

start = t()
x = 0
while x < 10000000:
    x += 1
time1 = t()
x = 0
while x < 10000000:
    x += 1
    if True:
        pass
time2 = t()

print(start)
print(time1 - start) # Time for simple while-loop
print(time2 - time1) # Time for while+if

A sample output would be:

1355517837.993
1.7850000858306885
1.7209999561309814

Which is completely counter-intuitive. The while-if-loop is working ever-so-slightly faster than the standard while-loop. This happens almost every time I run it; perhaps 1 in 20 times take longer. Does anyone know why?

like image 506
Yos233 Avatar asked Dec 14 '12 21:12

Yos233


People also ask

Why would you choose to use an IF statement over a while loop?

Meaning an if statement gives you once the possibility to do something or not (or something else). Whereas a while loop does things as long as the condition is true.

Is a while loop more efficient than a for loop?

As you can guess from most of these answers, the main advantage of a for loop over a while loop is readability. A for loop is a lot cleaner and a lot nicer to look at. It's also much easier to get stuck in an infinite loop with a while loop.

Does while loop work faster than for loop?

so none of them is faster than the other. Whatever may be the form of loop, the test condition will take same time.


2 Answers

The dis shows that there are more steps to the if statement while loop.

In [4]: dis.dis(t2)
  2           0 LOAD_CONST               1 (0)
              3 STORE_FAST               0 (x)

  3           6 SETUP_LOOP              26 (to 35)
        >>    9 LOAD_FAST                0 (x)
             12 LOAD_CONST               2 (10000000)
             15 COMPARE_OP               0 (<)
             18 POP_JUMP_IF_FALSE       34

  4          21 LOAD_FAST                0 (x)
             24 LOAD_CONST               3 (1)
             27 INPLACE_ADD
             28 STORE_FAST               0 (x)
             31 JUMP_ABSOLUTE            9
        >>   34 POP_BLOCK
        >>   35 LOAD_CONST               0 (None)
             38 RETURN_VALUE

In [5]: dis.dis(t1)
  2           0 LOAD_CONST               1 (0)
              3 STORE_FAST               0 (x)

  3           6 SETUP_LOOP              35 (to 44)
        >>    9 LOAD_FAST                0 (x)
             12 LOAD_CONST               2 (10000000)
             15 COMPARE_OP               0 (<)
             18 POP_JUMP_IF_FALSE       43

  4          21 LOAD_FAST                0 (x)
             24 LOAD_CONST               3 (1)
             27 INPLACE_ADD
             28 STORE_FAST               0 (x)

  5          31 LOAD_GLOBAL              0 (True)
             34 POP_JUMP_IF_FALSE        9

  6          37 JUMP_ABSOLUTE            9
             40 JUMP_ABSOLUTE            9
        >>   43 POP_BLOCK
        >>   44 LOAD_CONST               0 (None)
             47 RETURN_VALUE
like image 184
Jakob Bowyer Avatar answered Oct 05 '22 07:10

Jakob Bowyer


I'd guess that the compiler would remove the if True block since it is constant.

When I run I get mostly the opposite results from you. I may just be random effects of the execution environment.

1355519587.2 0.832797050476 1.04382395744

1355519590.03 0.863899946213 1.09347200394

1355519593.72 0.831655025482 1.05389809608

1355519599.71 0.831452131271 1.41783499718

1355519602.99 0.815280914307 1.05724310875

1355519605.72 0.826404094696 1.05700492859

1355519608.94 0.827296972275 1.07807898521

like image 25
Foo Avatar answered Oct 05 '22 07:10

Foo