Trond wrote:DisableDebugger isn't enough, because the optimizer is only enabled when the debugger is disabled totally (from the menu).
Ha, I actually got the DisableDebugger idea from you.
Physically turning off the Debugger on the GUI bought me another 15 ms.
I was thinking to concatenate strings in memory, but there is not much overhead doing it with PB arrays and then using CopyMemoryString() inside a Join() procedure. That leaves most of the memory management to PB.
Side note:
VB6 native string concatenation(&) is actually faster than PB. But, CopyMemoryString() blows it away and is easy to use.
Code: Select all
EnableExplicit
Procedure.s Join(Array sA.s(1), Delm$=#NULL$)
; REV: 110301, skywalk
; String Concatenate Speed Test w/DisableDebugger while Debugger ON
; Str + Str => 19234ms / 32000 Calls, StrSize = 160000
; CopyMemoryString() => 15ms / 32000 Calls, StrSize = 160000
; Join() => 47ms / 32000 Calls, StrSize = 160000
; String Concatenate Speed Test w/DisableDebugger while Debugger OFF
; Str + Str => 18938ms / 32000 Calls, StrSize = 160000
; CopyMemoryString() => 15ms / 32000 Calls, StrSize = 160000
; Join() => 32ms / 32000 Calls, StrSize = 160000
Protected.i i, k, *p, *buf, memlen
Protected.s r$
k = ArraySize(sA())
For i = 0 To k
memlen + MemoryStringLength(@sA(i)) + SizeOf(Character) ; account for #Null$
Next i
If Delm$
memlen + k * MemoryStringLength(@Delm$) + SizeOf(Character) ; Add room for Delimiters
EndIf
;If memlen < 1024: memlen = 1024: EndIf
*buf = AllocateMemory(memlen + 1)
If *buf
*p = *buf ; Create tracking pointer for concatenating memory
If memlen <= MemorySize(*p) ; Verify enough memory created
If Delm$
CopyMemoryString(@sA(0), @*p)
CopyMemoryString(@Delm$)
For i = 1 To k
CopyMemoryString(@sA(i))
CopyMemoryString(@Delm$)
Next i
Else
CopyMemoryString(@sA(0), @*p)
For i = 1 To k
CopyMemoryString(@sA(i))
Next i
EndIf
r$ = PeekS(*buf)
FreeMemory(*buf)
EndIf
EndIf
ProcedureReturn r$
EndProcedure
CompilerIf #PB_Compiler_Debugger
DisableDebugger ; Slightly faster if also disabled on GUI.
CompilerEndIf
#Tries = 32000
Define.i i,t1
Define.s S
Define.s STRPlusSTR$, Join$, CopyMemStr$
#StrToUse$ = "XYZ"
;- STRING+STRING
t1 = ElapsedMilliseconds()
For i = 0 To #Tries-1
S + #StrToUse$ + #CRLF$
Next
t1 = ElapsedMilliseconds()-t1
STRPlusSTR$ = "Str + Str => " + Str(t1) + "ms / " + Str(#Tries) + " Calls, StrSize = " + Str(MemoryStringLength(@S)) + #CRLF$ + #CRLF$
S = #NULL$
;- COPYMEMORYSTRING
t1 = ElapsedMilliseconds()
Define.i *p, *buf, memlen
S = #StrToUse$ + #CRLF$
*buf = AllocateMemory(#Tries*MemoryStringLength(@S)+SizeOf(Character))
*p = *Buf
memlen = MemorySize(*p)
If memlen
S = #StrToUse$ + #CRLF$
CopyMemoryString(@S, @*p)
For i = 1 To #Tries-1
S = #StrToUse$ + #CRLF$
CopyMemoryString(@S)
Next
S = PeekS(*buf)
FreeMemory(*buf)
EndIf
t1 = ElapsedMilliseconds()-t1
CopyMemStr$ = "CopyMemoryString() => " + Str(t1) + "ms / " + Str(#Tries) + " Calls, StrSize = " + Str(MemoryStringLength(@S)) + #CRLF$ + #CRLF$
S = #NULL$
;- JOIN
t1 = ElapsedMilliseconds()
; Create array of Strings
Dim sA.s(#Tries-1)
For i = 0 To #Tries-1
sA(i) = #StrToUse$ + #CRLF$
Next i
S = Join(sA())
t1 = ElapsedMilliseconds()-t1
Join$ = "Join() => " + Str(t1) + "ms / " + Str(#Tries) + " Calls, StrSize = " + Str(MemoryStringLength(@S))
S = #NULL$
MessageRequester("String Concatenate Speed Test",STRPlusSTR$+CopyMemStr$+Join$)
Edited: Fixed Join() IMA if appending with delimiters. Allocated Memory was short by a #Null$.
The nice thing about standards is there are so many to choose from. ~ Andrew Tanenbaum