Last active
January 14, 2025 23:43
-
-
Save RickStrahl/80db974acfc450712400353dd65a1fbf to your computer and use it in GitHub Desktop.
Demonstrate FoxPro slow Method call vs direct call.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
************************************************************* | |
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