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