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. |