Author Topic: (Optimization) - Get 40% Speed Improvement with just adding one word  (Read 3971 times)

0 Members and 1 Guest are viewing this topic.

Offline Theo Gottwald

  • Administrator
  • Hero Member
  • *****
  • Posts: 918
    • it-berater
REGISTER is not often used, if I look in the postings here.

Seeing that, I wanted to test how big the difference is in a real case.

I have taken the INSTR-Code from Edwin as an Example because it shows very good how to do it.

The word we have to change is: LOCAL we change it into REGISTER.
But which one?

We look for Loops and count occurences. Inner Loops are better then outer Loops.

By just adding:
    REGISTER nByte  AS LONG, nByteMatch  AS LONG

we get the same result in just 65% of the time the original subprogram needs.

And maybe the program even gets a few bytes shorter because the ASM Code for register operations is shorter then the code using memory.
The bytes-saving may not be really of interest to you, but it will make the code to fit better into the CPU cache. Therefore size matters because "smaller=faster".

Please note that PB would assign the registers automatically if no REGISTER variables are explicitly declared.
Anyway the registers are been assigned to the first variables the compiler finds, in that order.
And if these are not the Loop-variables, its of no big advantage.


Code: [Select]
'---------------------------------------------------------------------------
' Fast Instr() replacement, also case insensitive possible.
' Accepts by pointer+length or by dynamic string.
' Original Version by Edwin Knoppert
'
' %MOD_INSTRPTR_EXPORT for export

' Instr by pointer.
FUNCTION Instr_ByPtr( _
      BYVAL nStartPos       AS LONG _
    , BYVAL pData           AS LONG _
    , BYVAL nDataLen        AS LONG _
    , BYVAL sMatchString    AS STRING _
    , BYVAL bMatchCase      AS LONG _
    ) AS LONG
   
' ------------ this Line has been changed --------
    REGISTER nByte  AS LONG, nByteMatch  AS LONG
'------------------------------------------------
    LOCAL pBYT        AS BYTE PTR
    LOCAL pBYTASCII   AS BYTE PTR
    LOCAL nLenMatch   AS LONG
    LOCAL bStartByte  AS BYTE
    LOCAL pBYTMatch   AS BYTE PTR
    LOCAL bFalse      AS LONG

    STATIC sAscii   AS STRING

    IF pData < 0 THEN EXIT FUNCTION
    IF nDataLen < 1 THEN EXIT FUNCTION
    IF nDataLen < LEN( sMatchString ) THEN EXIT FUNCTION

    nLenMatch = LEN( sMatchString )
    IF nLenMatch = 0 THEN EXIT FUNCTION

    nStartPos = MAX( 1, nStartPos )

    IF nStartPos + nLenMatch - 1 > nDataLen THEN EXIT FUNCTION
    DECR nStartPos

    IF LEN( sAscii ) = 0 THEN sAscii = CHR$( 0 TO 255 ): CharUpperBuff BYVAL STRPTR( sAscii ), LEN( sAscii )
    pBYTASCII = STRPTR( sAscii )

    ' Make uppercase if case isn't important.
    IF bMatchCase = 0 THEN
        pBYT = STRPTR( sMatchString )
        FOR nByte = 0 TO LEN( sMatchString ) - 1: @pBYT[nByte] = @pBYTASCII[@pBYT[nByte]]: NEXT nByte
    END IF

    pBYT        = pData
    pBYTMatch   = STRPTR( sMatchString )
    bStartByte  = @pBYTMatch[0]

    IF bMatchCase THEN
        FOR nByte = nStartPos TO nDataLen - nLenMatch - 0
            IF @pBYT[nByte] = bStartByte THEN
                bFalse = 0
                FOR nByteMatch = 1 TO nLenMatch - 1
                    IF @pBYT[nByte+nByteMatch] <> @pBYTMatch[nByteMatch] THEN bFalse = 1: EXIT FOR
                NEXT nByteMatch
                IF bFalse = 0 THEN FUNCTION = nByte + 1: EXIT FOR
            END IF
        NEXT nByte
    ELSE
        FOR nByte = nStartPos TO nDataLen - nLenMatch - 0
            IF @pBYTASCII[@pBYT[nByte]] = bStartByte THEN
                bFalse = 0
                FOR nByteMatch = 1 TO nLenMatch - 1
                    IF @pBYTASCII[@pBYT[nByte+nByteMatch]] <> @pBYTMatch[nByteMatch] THEN bFalse = 1: EXIT FOR
                NEXT nByteMatch
                IF bFalse = 0 THEN FUNCTION = nByte + 1: EXIT FOR
            END IF
        NEXT nByte
    END IF

END FUNCTION

' Instr by string (not asciiz).
FUNCTION Instrbs(BYREF sData AS STRING,BYVAL sMatchString AS STRING,OPT BYVAL nStartPos AS LONG, OPT BYVAL bMatchCase AS LONG) AS LONG
    FUNCTION = Instr_ByPtr( nStartPos, STRPTR( sData ), LEN( sData ), sMatchString, bMatchCase )
END FUNCTION

'---------------------------------------------------------------------------
#ENDIF
« Last Edit: July 28, 2007, 12:22:47 PM by Theo Gottwald »