Code: Select all
; cat.pbi --- for fast string concatenation
Structure CatBuffer
capacity.i
length.i
text.s
EndStructure
Procedure EmptyCatBuffer(*cat.CatBuffer)
Protected blank$ = ""
*cat\capacity = 0
*cat\length = 0
PokeS(@*cat\text, blank$, 0)
EndProcedure
Procedure AddToCatBuffer(*cat.CatBuffer, string$)
; Appends string$ to the buffer. If the buffer is too small, this procedure
; will double the buffer's size before appending the string. Simply doubling
; the size on overflow uses more memory but necessitates fewer reallocations
; of memory as the buffer grows.
Protected new_length = *cat\length + StringByteLength(string$)
Protected new_capacity, old_text$, *address
If new_length > *cat\capacity
new_capacity = *cat\capacity
If new_capacity = 0
new_capacity = 1024 * 4
EndIf
While new_length > new_capacity
new_capacity * 2
Wend
old_text$ = *cat\text
*cat\text = Space(new_capacity)
*cat\capacity = new_capacity
PokeS(@*cat\text, old_text$)
EndIf
*address = @*cat\text + *cat\length
PokeS(*address, string$)
*cat\length = new_length
EndProcedure
Here's some test code I wrote:
Code: Select all
EnableExplicit
XIncludeFile "cat.pbi"
Procedure TestCatBuffer()
Protected cat.CatBuffer, t$
t$ = "The "
AddToCatBuffer(cat, t$) : Debug cat\text
t$ = "quick "
AddToCatBuffer(cat, t$) : Debug cat\text
t$ = "brown fox jumps over the lazy dog."
AddToCatBuffer(cat, t$) : Debug cat\text
t$ = " Pack my box with five dozen liquor jugs."
AddToCatBuffer(cat, t$) : Debug cat\text
EmptyCatBuffer(cat) : Debug cat\text
t$ = "A fresh new sentence."
AddToCatBuffer(cat, t$) : Debug cat\text
EndProcedure
Procedure TestCatBufferSpeed(count.i)
Protected cat.CatBuffer, t$, i, msec
Debug "SPEED OF CATBUFFER (" + FormatNumber(count, 0) + " iterations):"
msec = ElapsedMilliseconds()
For i = 1 To count
AddToCatBuffer(cat, " add")
Next
msec = ElapsedMilliseconds() - msec
Debug "-- " + FormatNumber(msec/1000, 3) + " seconds."
Debug "-- " + FormatNumber(Len(cat\text), 0) + " characters in buffer."
Debug "SPEED OF '+' (" + FormatNumber(count, 0) + " iterations):"
msec = ElapsedMilliseconds()
For i = 1 To count
t$ + " add"
Next
msec = ElapsedMilliseconds() - msec
Debug "-- " + FormatNumber(msec/1000, 3) + " seconds."
Debug "-- " + FormatNumber(Len(t$), 0) + " characters in string."
EndProcedure
TestCatBuffer()
TestCatBufferSpeed(1000)