• Welcome to Powerbasic Museum 2020-B.
 

(Optimization) Use IIF& () or better IF .. THEN ?

Started by Theo Gottwald, August 06, 2007, 09:13:44 AM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Theo Gottwald

Very short code in Basic:

IIF&(R01,10,11)

Which will do just the same as this:

IF R01 THEN R02=10& ELSE R02=11&

Lets take a look at the ASM-Level if there are differences.


EXAMPLE 1: IF .. THEN / IIF& using LONG.
We can see that the IF ... THEN makes better use of REGISTER VARIABLES, if they are used.

SUB TestfuncA()
REGISTER R01 AS LONG,R02 AS LONG
    !NOP
R01=100
    !NOP
R02=IIF&(R01,10&,11&)
    ! NOP
    IF R01 THEN R02=10& ELSE R02=11&
    !NOP
END SUB

' becomes

4023CE  NOP
4023CF  MOV ESI, DWORD 00000064
4023D5  NOP
'--------------------------------------------------------
' This is the IIF&
'--------------------------------------------------------
4023D6  MOV EAX, ESI
4023D8  TEST EAX, EAX
4023DA  JZ  SHORT L4023E3
4023DC  MOV EAX, DWORD 0000000A
4023E1  JMP SHORT L4023E8
4023E3  MOV EAX, DWORD 0000000B
4023E8  MOV EDI, EAX
4023EA  NOP
'--------------------------------------------------------
' This is the IF ... THEN
'--------------------------------------------------------
4023EB  MOV EAX, ESI
4023ED  TEST EAX, EAX
4023EF  JZ  SHORT L4023F9
4023F1  MOV EDI, DWORD 0000000A
4023F7  JMP SHORT L4023FF
4023F9  MOV EDI, DWORD 0000000B
4023FF  NOP


EXAMPLE 2: Same code - just normal local variables (no REGISTER variables).
Even in this case, the IF ... THEN is slightly better optimized.
Lets say that when using IIF& the difference is not really big.
This will change in exmple 3.

SUB TestfuncA()
#REGISTER NONE
LOCAL R01 AS LONG,R02 AS LONG
    !NOP
R01=100
    !NOP
R02=IIF&(R01,10&,11&)
    ! NOP
    IF R01 THEN R02=10& ELSE R02=11&
    !NOP
END SUB 

4023CC  NOP
4023CD  MOV DWORD PTR [EBP+FFFFFF78], DWORD 00000064
4023D7  NOP
'--------------------------------------------------------
' This is the IIF&
'--------------------------------------------------------
4023D8  MOV EAX, DWORD PTR [EBP+FFFFFF78]
4023DE  TEST EAX, EAX
4023E0  JZ  SHORT L4023E9
4023E2  MOV EAX, DWORD 0000000A
4023E7  JMP SHORT L4023EE
4023E9  MOV EAX, DWORD 0000000B
4023EE  MOV DWORD PTR [EBP+FFFFFF74], EAX
4023F4  NOP
'--------------------------------------------------------
' This is the IF ... THEN
'--------------------------------------------------------
4023F5  MOV EAX, DWORD PTR [EBP+FFFFFF78]
4023FB  TEST EAX, EAX
4023FD  JZ  SHORT L40240B
4023FF  MOV DWORD PTR [EBP+FFFFFF74], DWORD 0000000A
402409  JMP SHORT L402415
40240B  MOV DWORD PTR [EBP+FFFFFF74], DWORD 0000000B
402415  NOP


EXAMPLE 3:
Using IIF() instead of IIF&().
What we are doing is, we use the wrong command. Because IIF() can be used for all types of numeric variables, internally floating point mnemonics are beeing used. This is much more expensive in terms of CPU cycles then the normal IIF&().

The code is the same as in example 2, just the IIF&() is replaced by a IIF(). As in the ASM-Part the IF ... THEN Part does not change, we left it away in the following Listing.


'--------------------------------------------------------
' This is the IIF()
'--------------------------------------------------------
4023D6  MOV EAX, ESI
4023D8  TEST EAX, EAX
4023DA  JZ  SHORT L4023E4
4023DC  FILD INTEGER PTR [00406734]
4023E2  JMP SHORT L4023EA
4023E4  FILD INTEGER PTR [00406738]
4023EA  FISTP QUAD PTR [EBP-5C]
4023ED  MOV EDI, DWORD PTR [EBP-5C]
4023F0  NOP


Conclusion:
As expected, its not a big difference if we use IF .. THEN or IIF&().
It will use more CPU cycles, if we forget the & after the IIF and use IIF() instead of IIF&().