LoginLogin

IF THEN speed?

Root / Programming Questions / [.]

LeminWedjCreated:
I need to know for micro-optimization's sake, is it faster to process IF THEN lists like this
IF VAR2==0 THEN BEEP 9
IF VAR2==1 THEN BGMPLAY ":0 D16D16<D8>A8"
IF VAR2==2 THEN INC DDIP%
IF VAR2==3 THEN DEC DDIP%
or like this
IF VAR2==0 THEN BEEP 9
ELSEIF VAR2==1 THEN BGMPLAY ":0 D16D16<D8>A8"
ELSEIF VAR2==2 THEN INC DDIP%
ELSEIF VAR2==3 THEN DEC DDIP%
ENDIF

this should be obvious The forms are not equivalent Form 1 looks like this:
if var2 != 0 jmp @1
  beep 9
@1
if var2 != 1 jmp @2
  bgmplay ...
@2
...
@4
...
Form 2 looks like this
if var2 != 0 jmp @1
  beep 9
  jmp @end
@1
if var2 != 1 jmp @2
  bgmplay ...
  jmp @end
@2
...
@end
The difference is that the second form, on finding a successful case, does not have to evaluate all the other comparisons. If the value of VAR2 is randomly and uniformly distributed across [0,3] then on average it will evaluate 2 of the four cases before succeeding. Edit: this is ONLY for mutually exclusive cases, where you only want one outcome, though. If it's possible to execute multiple cases in one pass (like for checking multiple button states), you can't use ELSEIF here for the same reason: you don't want to skip over that intersecting check.
evil goto modeFor the sake of completeness, ON GOTO is faster here because it just uses an index instead of doing any comparisons:
'Precondition: 
'  VAR2 is between -1 and 3 inclusive
ON VAR2 GOTO @0,@1,@2,@3
GOTO @break
@0 
  BEEP 9
  GOTO @break
@1
  BGMPLAY ...
  GOTO @break
@2
  INC DDIP%
  GOTO @break
@3
  DEC DDIP%
@break

DIM I
DIM M,IM,N
DIM ITR=10000
FOR I=0 TO ITR-1
 N=RND(20)
 M=MILLISEC
 IF N==0 THEN ENDIF
 IF N==1 THEN ENDIF
 IF N==2 THEN ENDIF
 '...
 IF N==18 THEN ENDIF
 IF N==19 THEN ENDIF
 M=MILLISEC-M
 INC IM,M
NEXT I
?IM/ITR

IM=0
FOR I=0 TO ITR-1
 N=RND(20)
 M=MILLISEC
 IF N==0 THEN
 ELSEIF N==1 THEN
 ELSEIF N==2 THEN
 '...
 ELSEIF N==18 THEN
 ELSEIF N==19 THEN
 ENDIF
 M=MILLISEC-M
 INC IM,M
NEXT I
?IM/ITR
Interestingly, using ELSEIF statements seems to run a whole 25-30% faster on average, on the order of thousandths of a millisecond. Much lower a difference than I thought. When you reiterate the two loops hundreds of times, multiple IF lines take around 0.00960 +/-0.00020 milliseconds, while ELSEIF blocks take around 0.00683 +/-0.00002 milliseconds. Some of this could probably be attributed to randomness. More IF statements should increase accuracy.

ON GOTO would be slightly faster, but I don't think it's worth using until you have ~10 conditions.

To spin this away from optimization and into code quality: IF ELSEIF ENDIF blocks by design evaluate the conditions from first to last, act upon the first true condition (if it is found,) and stop evaluating all after (if they exist.) So in conditions that are mutually exclusive or you want to guarantee act exclusively it is better for your code to use an ELSEIF than a chain of individual IF blocks. In the example you give all of the conditions are mutually exclusive (VAR2 can't be two different values at once since it's not a quantum particle) so you should use an ELSEIF. And like they said above yes it is faster.

So from what iā€™m getting, ELSEIF is indeed faster, but once the list gets above ~10 things, ON GOTO would be faster. Very helpful for me since I feel like the way I program right now is unoptimized as hell. Thanks for the info, guys.

So from what iā€™m getting, ELSEIF is indeed faster, but once the list gets above ~10 things, ON GOTO would be faster. Very helpful for me since I feel like the way I program right now is unoptimized as hell. Thanks for the info, guys.
Micro optimizations like this are not worth it at the cost of how terrible your code style and maintainability becomes. These are fixes on the orders of hundredths of milliseconds. Just learn to macro-optimize your code in places that are actually slow. ON GOTO is the actual worst ever. EDIT: well learning this stuff will probably improve your standing in OSP contests but not actual programs.

(ON GOTO is always faster, but it's such a minor difference that it's only worth using when it makes your code more readable, which I think usually happens once you reach maybe 10 items I guess)