Stringbuilder
Community Forums/Showcase/Stringbuilder
| ||
| Here is some code for concatenating strings using a stringbuilder instead of directly adding strings together. [Edit] Modified the increasefactor to allow smaller increases of the array.
'String Concatenation test...
'Pretty memoryconsumptive but WAY faster than OrgString = OrgString + NewString
'The memoryconsumption Vs speed can be balanced with the IncreaseFactor, but depends alot on your computer-specs.
Type StringBuilder
Field Initsize:Int
Field Currentsize:Int
Field Stringsize:Int
Field StrArray:Byte[]
Const IncreaseFactor:Float = 1.0 ' Increase the buffersize by 100 % (!!! never below or equal to 0 !!!)
Method New()
Initsize = 4096
Currentsize = Initsize
Stringsize = 0
StrArray = New Byte[Initsize]
End Method
Method Append(txt:String)
Local DstPtr:Byte Ptr
Local SrcPtr:Byte Ptr
If Stringsize + txt.length < Currentsize Then
' There is enough room, add the string to the stringbuilder
DstPtr = Byte Ptr(StrArray)
DstPtr :+ Stringsize
SrcPtr = Byte Ptr(txt)
MemCopy (DstPtr,SrcPtr,txt.length)
Stringsize :+ txt.length
FlushMem()
Else
' There is not enough room left, resize the array to double size
'TODO: Calculate the needed size at once to reduce several resizes of the array to just one if the inputstring is larger than the increased size.
While Stringsize + txt.length > Currentsize
StrArray = StrArray[..Currentsize+(Currentsize*IncreaseFactor)] ' Resize the current array
CurrentSize :+ Currentsize*IncreaseFactor
Wend
DstPtr = Byte Ptr(StrArray)
DstPtr :+ Stringsize
SrcPtr = Byte Ptr(txt)
MemCopy (DstPtr,SrcPtr,txt.length)
Stringsize :+ txt.length
FlushMem()
EndIf
End Method
Method GetString:String()
Return String.FromCString(Byte Ptr(StrArray))
End Method
End Type
' String Concatenation using a Stringbuilder
Local StrBuilder:StringBuilder = New StringBuilder
Local FinalStr:String
Local Loops:Int = 10000
Local i:Int
Local StartTime:Int
Local EndTime:Int
StartTime = MilliSecs()
For i = 1 To Loops
StrBuilder.Append("Test " + Chr(13) + Chr(10))
Next
EndTime = MilliSecs()
FinalStr = StrBuilder.GetString()
Print "StringLength: "+String.FromInt(FinalStr.Length)
Print "Elapsed time: "+String.FromInt(EndTime-StartTime) + " ms"
Print "The StringBuilder buffer increased to a size of "+String.FromInt(StrBuilder.CurrentSize) + " bytes"
'file = WriteFile("C:\output.txt")
'WriteString file,FinalStr
'CloseStream file
End
Then run the code below and compare the speed... ' String concatenation using the "standard" method Local FinalStr:String Local Loops:Int = 10000 Local i:Int Local StartTime:Int Local EndTime:Int StartTime = MilliSecs() For i = 1 To Loops FinalStr :+ "Test " + Chr(13) + Chr(10) FlushMem ' If you remove this your computers memory will be sucked dry in a few seconds... Next EndTime = MilliSecs() Print "StringLength: "+String.FromInt(FinalStr.Length) Print "Elapsed time: "+String.FromInt(EndTime-StartTime) + " ms" Feel free to use it and modify it as you wish. Suggestions and improvements are also welcome. |