Optimization question from a reader


I received a question:


 


…I’ve always been curious about code like this:

IF wParam=ASC(“a”)
    wParam=ASC(“b”)
ENDIF

Is it more appropriate to think of ASC(“a”) as the Fox equivalent of a C ‘a’, or is it an actual function call every time through?


 


It’s easy to test this.


Try running this code:


 


 


num=1e7     && 1e7 is 10 * 1e6 (3,6,9 are thousand, million, billion)  = 10 * 1 million


wParam=ASC(“a”)


ns=SECONDS()


FOR i  = 1 TO num


      IF wParam=ASC(“a”)


            wParam=ASC(“b”)


      ENDIF


ENDFOR


 


nd1=SECONDS()-ns


?nd1


 


ns=SECONDS()


FOR i  = 1 TO num


      IF wParam=97


            wParam=98


      ENDIF


ENDFOR


 


nd2=SECONDS()-ns


?nd2,100*(nd1-nd2)/nd2


 


 


 


On my machine, the 2nd loop is 20-25% faster.


 


Of course an optimizing compiler could transform the 1st loop to the 2nd. In fact, a really good optimizing compiler would remove the loop completely!


 


In C and C++, the literal ‘a’ is exactly equal to 97, even at runtime, whereas the literal “a” (notice the single vs double quotes) is a string represented as a 2 byte array of 97 followed by a terminating 0.


 


The ASC() function takes any string expression as a parameter, including possibly a function call, so it cannot be optimized out in general.


 


 

Comments (1)

  1. Fabio Lunardon says:

    I know the answer,

    but it can be interesting if you explain

    to the public because in the following’s code

    the last loop it is 8 -10 % faster.

    num=1e7

    wParam=ASC("a")

    ns=SECONDS()

    FOR i = 1 TO num

    ENDFOR

    nd0=SECONDS()-ns

    ns=SECONDS()

    FOR i = 1 TO num

    IF wParam=97

    wParam = 98

    ENDIF

    ENDFOR

    nd1=SECONDS()-ns

    ns=SECONDS()

    FOR i = 1 TO num

    IF wParam#97

    LOOP

    ENDIF

    wParam = 98

    ENDFOR

    nd2=SECONDS()-ns

    ?nd1,nd2,100*(nd1-nd2)/(nd2-nd0)