Announcement

Collapse
No announcement yet.

BYVAL or BYREF

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • BYVAL or BYREF

    Just reading the manual (yes I'm strange) for FUNCTION

    arguments
    <snip>
    Normally, PowerBASIC passes parameters to a Function either by reference (BYREF) or by copy (BYCOPY). Either way, the address of the variable is passed and the procedure has to look at that address to get the value of the parameter. If you do not need to modify the parameters (true in many cases), you can speed up your calls by passing the parameters by value using the BYVAL keyword.
    I don't understand this. Surely the fastest way to pass data is by passing a pointer to the data, rather than the data itself. If I read correctly parameters are passed on the stack, so a push of a pointer then a corresponding pop would be a lot faster then push(ing) clumps of data.

    What am I missing here?

    Can someone explain please?


    Pat

  • #2
    When passed BYVAL the param does not have to be dereferenced when used in the called function by value. Of course, it has to be dereferenced at the point of the call so the value can be pushed on the stack, so you only "win" by changing to BYVAL if the parameter is used more than once by value in the called procedure.

    The bottom line is... it's probably not worth losing a whole lot of sleep over.
    Michael Mattias
    Tal Systems (retired)
    Port Washington WI USA
    [email protected]
    http://www.talsystems.com

    Comment


    • #3
      I ran the below test code, and saw a few % increase in speed using BYVAL when passing LONG parameters, but when passing floating point--especially EXT--parameters, BYVAL significantly slowed the code.

      Slowest of all, which should be avoided, is BYVAL x AS STRING

      Code:
      #COMPILE EXE
      #DIM ALL
      
      FUNCTION test1(x AS LONG, y AS LONG, z AS LONG) AS LONG
          FUNCTION = 1
      END FUNCTION
      FUNCTION test2(x AS EXT, y AS EXT, z AS EXT) AS LONG
          FUNCTION = 1
      END FUNCTION
      FUNCTION test3(BYVAL x AS LONG, BYVAL y AS LONG, BYVAL z AS LONG) AS LONG
          FUNCTION = 1
      END FUNCTION
      FUNCTION test4(BYVAL x AS EXT, BYVAL y AS EXT, BYVAL z AS EXT) AS LONG
          FUNCTION = 1
      END FUNCTION
      
      FUNCTION PBMAIN () AS LONG
         LOCAL ii,xLong,yLong,zLong AS LONG
         LOCAL xExt,yExt,zExt AS EXT
         LOCAL t1,t2,t3,t4 AS QUAD
         
         TIX t1
          FOR ii = 1 TO 10000000
             test1(xLong, yLong, zLong)
          NEXT
         TIX END t1
      
         TIX t2
          FOR ii = 1 TO 10000000
             test3(xLong, yLong, zLong)
          NEXT
         TIX END t2
             
         TIX t3
          FOR ii = 1 TO 10000000
             test2(xExt, yExt, zExt)
          NEXT
         TIX END t3
      
         TIX t4
          FOR ii = 1 TO 10000000
             test4(xExt, yExt, zExt)
          NEXT
         TIX END t4
         
         ? "byref Long" & STR$(t1) & $CRLF & "byval Long" &  STR$(t2) & $CRLF & "byref float" & STR$(t3) & $CRLF & "byval float" & STR$(t4)
      END FUNCTION

      Comment


      • #4
        Pat,
        a push of a pointer then a corresponding pop would be a lot faster then push(ing) clumps of data
        Parameter addresses are 32 bits so if the data type is 32 bits or less then there is no more information to be pushed on the stack when passed ByVal than when passed ByRef.
        When passed ByVal there is a very small potential saving because one level of indirection is needed with ByRef which is not needed with ByVal.

        Paul.

        Comment

        Working...
        X