Skip to content

Instantly share code, notes, and snippets.

@RickStrahl
Last active January 14, 2025 23:43
Show Gist options
  • Save RickStrahl/80db974acfc450712400353dd65a1fbf to your computer and use it in GitHub Desktop.
Save RickStrahl/80db974acfc450712400353dd65a1fbf to your computer and use it in GitHub Desktop.
Demonstrate FoxPro slow Method call vs direct call.
CLEAR
SET PROCEDURE TO wwapi ADDITIVE && or whereever wwHeap lives
LOCAL loHeap as wwHeap
loHeap = CREATEOBJECT("wwHeap")
lnIterations = 10000000 && 10 million characters
lcData = REPLICATE("0123456789",lnIterations / 10)
loHeap.SetData(lcData)
*** Using a method call
lnStart = SECONDS()
FOR x = 1 TO lnIterations
lcChar = loHeap.Getbytes(x,1)
* ?lcChar
ENDFOR
? SECONDS() - lnStart && 5.0 seconds
*** Same without a method call
lnStart = SECONDS()
FOR x = 1 TO lnIterations
*** No method call
lcChar = Sys(2600,loHeap.nBaseAddress-1 + x,1)
*?lcChar
ENDFOR
? SECONDS() - lnStart && 1.3 seconds
loHeap.Release()
RETURN
*************************************************************
DEFINE CLASS wwHeap AS Custom
*************************************************************
*: Author: Rick Strahl
*: (c) West Wind Technologies, 2025
*:Contact: http://www.west-wind.com
*:Created: 01/14/2025
*************************************************************
#IF .F.
*:Help Documentation
*:Topic:
Class wwHeap
*:Description:
Class that wraps the Windows Heap for the active process and
allows direct access to memory. Very useful for quickly
iterating over strings character by character without the
massive slowdown that's caused by FoxPro's SUBSTR() function.
*:Example:
*:Remarks:
*:SeeAlso:
*:ENDHELP
#ENDIF
*** Custom Properties
*** Stock Properties
nBaseAddress = -1
PROCEDURE Init()
Declare Integer HeapAlloc in Win32Api Integer, Integer, Integer
Declare Integer HeapFree in Win32APi Integer, Integer, Integer
Declare Long GetProcessHeap in Win32API
ENDPROC
************************************************************************
* Allocate
****************************************
*** Function:
*** Assume:
*** Pass:
*** Return:
************************************************************************
FUNCTION Allocate(lnSize, lcData)
this.nBaseAddress = HeapAlloc(GetProcessHeap(), 0, lnSize)
IF VARTYPE(lcData) = "C" OR VARTYPE(lcData) = "Q"
SetHeapData(lcData)
ENDIF
RETURN this.nBaseAddress
ENDFUNC
* Allocate
************************************************************************
* SetHeapData
****************************************
*** Function: Assigns a value to the allocated heap
*** Assume: Creates
*** Pass:
*** Return:
************************************************************************
FUNCTION SetData(lcData)
IF(this.nBaseAddress = -1)
this.Allocate(LEN(lcData))
ENDIF
SYS(2600, this.nBaseAddress, LEN(lcData), lcData)
RETURN
ENDFUNC
* SetHeapData
************************************************************************
* GetBytes
****************************************
*** Function:
*** Assume: Making the SYS(2600) call directly is much more
*** efficient so consider directly calling it.
*** Pass: lnOffset into the heap buffer
*** lnCount number of characters/bytes to returns
*** Return: return characters/bytes
************************************************************************
FUNCTION GetBytes(lnOffSet, lnCount)
IF EMPTY(lnCount)
lnCount = 1
ENDIF
RETURN Sys(2600,this.nBaseAddress-1 + lnOffSet, lnCount)
ENDFUNC
* GetBytes
************************************************************************
* ReleaseHeap
****************************************
*** Function:
*** Assume:
*** Pass:
*** Return:
************************************************************************
FUNCTION Release()
IF this.nBaseAddress = -1
RETURN
ENDIF
HeapFree( GetProcessHeap(), 0, this.nBaseAddress)
this.nBaseAddress = -1
ENDFUNC
* ReleaseHeap
************************************************************************
* Destroy
****************************************
FUNCTION Destroy()
THIS.Release()
ENDFUNC
* Destroy
ENDDEFINE
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment