PDA

View Full Version : StringBuilder for ThinBASIC @ GitHub



Petr Schreiber
02-08-2014, 15:21
Hi all,

I am sure you are all familiar with the concept of StringBuilder - it is little helper which performs efficient string concatenations and often much more. I started working on such a component for ThinBASIC - the language has incredibly epic string handling, but didn't have any stringbuilder... till now!

The usage
... is very simple. You instantiate object, and then use its methods:


Uses "StringBuilder", "Console"

Function TBMain()

Dim stringBuffer As String
Dim sb As StringBuilder
sb = New StringBuilder()

Long i

Dim stopWatch As cTimer
stopWatch = New cTimer()

Print "Appending to classic string: "
stopWatch.Start
For i = 1 To 20000
stringBuffer += "Appending is fine!"
Next
stopWatch.Stop
PrintL stopWatch.ElapsedToString(%CTIMER_MILLISECONDS, "0") + " ms (Total " + Len(stringBuffer) + " characters)"

Print "Appending to string builder: "
stopWatch.Start
For i = 1 To 20000
sb.Add("Appending is fine!")
Next
stopWatch.Stop
PrintL stopWatch.ElapsedToString(%CTIMER_MILLISECONDS, "0") + " ms (Total " + Len(sb.ToString()) + " characters)"

PrintL
PrintL "Press any key to quit..."

WaitKey

End Function


What is it good for?
It is great for efficient string appending. Do you see the code above? Check the speed on your PC or see the screenshot...

The source code
I decided to make the code public, to make possible for others to commit their enhancements. Get the source @GitHub:
https://github.com/petrSchreiber/thinBasic_StringBuilder

The binaries
Please note StringBuilder is official part of thinBasic since 1.9.16.17! Yay!
You can still grab the latest release (https://github.com/petrSchreiber/thinBasic_StringBuilder/releases/latest) from GitHub as well.

Documentation
The documentation is provided at Wiki associated with the repository, please check here:
https://github.com/petrSchreiber/thinBasic_StringBuilder/wiki

Petr

mike lobanovsky
02-08-2014, 21:02
Hi Petr,

The timings are really impressive.

How would you comment on the following script and the associated snapshot, please?


Uses "StringBuilder", "Console"

Function TBMain()

Long i

For i = 1 To 2000000
SpawnStringBuilder
Next

PrintL "Press any key to quit..."

WaitKey

End Function

Sub SpawnStringBuilder()
Dim sb As StringBuilder
sb = New StringBuilder()

sb.Capacity = 10000
sb.Clear()
End Sub

Petr Schreiber
02-08-2014, 21:17
Hi Mike,

well, that cries "memory leak" :) I am looking into it right now...


Petr

Petr Schreiber
02-08-2014, 21:25
Thank you Mike,

I forgot the destruction must be handled on module side - now fixed.

Please redownload the DLL, and if curious, check the change in commit at git (https://github.com/petrSchreiber/thinBasic_StringBuilder/commit/898ff487a9f0f24181e17d4ad9b2f5dd0cee792b).

Early versions of the SDK freed the object, but when we discussed with Eros possiblity of non-COM based objects, it was changed to be freed by module creator.

From thinBasic programmer point of view, all objects are garbage collected - destuctor is called once they run out of scope.


Petr

mike lobanovsky
03-08-2014, 04:10
Thanks a lot Petr,

In fact, git was the first place I poked my nose into. :) Now everything seems to be running just fine even without the sb.Clear() call.

Petr Schreiber
01-02-2015, 14:42
Updated the module:

.Add method can now take any number of parameters


Few tips on when to use this:


Uses "StringBuilder", "Console"

Function TBMain()

Dim stringBuffer As String
Dim sb As StringBuilder
sb = New StringBuilder()

Long i

Dim stopWatch As cTimer
stopWatch = New cTimer()

PrintL "Appending to classic string: "
stopWatch.Start
For i = 1 To 20000
stringBuffer += "Appending is fine! (" + i + ")"
Next
stopWatch.Stop
PrintL stopWatch.ElapsedToString(%CTIMER_MILLISECONDS, "0") + " ms (Total " + Len(stringBuffer) + " characters)"

PrintL
PrintL "Appending to classic string with StrFormat$: "
stringBuffer = ""
stopWatch.Start
For i = 1 To 20000
stringBuffer += StrFormat$("Appending is fine! ({1})", i)
Next
stopWatch.Stop
PrintL stopWatch.ElapsedToString(%CTIMER_MILLISECONDS, "0") + " ms (Total " + Len(stringBuffer) + " characters)"

PrintL
PrintL "Appending to string builder with StrFormat$: "
stopWatch.Start
For i = 1 To 20000
sb.Add(StrFormat$("Appending is fine! ({1})", i))
Next
stopWatch.Stop
PrintL stopWatch.ElapsedToString(%CTIMER_MILLISECONDS, "0") + " ms (Total " + Len(sb.ToString()) + " characters)"

PrintL
PrintL "Appending to string builder with multiple parameters: "
sb.Clear()
stopWatch.Start
For i = 1 To 20000
sb.Add("Appending is fine! (", i, ")")
Next
stopWatch.Stop
PrintL stopWatch.ElapsedToString(%CTIMER_MILLISECONDS, "0") + " ms (Total " + Len(sb.ToString()) + " characters)"

PrintL
printl "Press any key to quit..."

WaitKey

End Function



Petr

primo
16-12-2016, 22:18
Hi Petr
in the wiki you said :Place the thinBasic_stringBuilder.dll to Mod directory inside your thinBasic installation
but it seems the binary thinBasic_stringBuilder.dll is from 2015 while the source code is from 2016. even the old dll works but i want to be sure it is the correct file
the dll i found inside thinBasic_StringBuilder.zip.
thanks

Petr Schreiber
17-12-2016, 11:58
Hi Primo,

thanks for letting me know. StringBuilder is now part of ThinBASIC default installation, you don't have to get it from GitHub, if you don't want to.
The binaries there are fresh!:
https://github.com/petrSchreiber/thinBasic_StringBuilder/releases/tag/1.9.16.17


Petr

Petr Schreiber
09-04-2017, 18:10
I prepared new version of stringBuilder for thinBasic 1.9.16.18.
Users of older version can download the binaries here: https://github.com/petrSchreiber/thinBasic_StringBuilder/releases/tag/1.9.16.18

What is new? I added the DataPtr read-only property, which is handy for cases when you want to work with stringBuilders internal memory directly, for enhanced performance.
Full documentation here: https://github.com/petrSchreiber/thinBasic_StringBuilder/wiki


Petr

primo
12-04-2017, 08:07
Thanks Petr for the additional property DataPtr
i have tried it like this, but not sure if this is the correct usage:

Uses "StringBuilder", "Console"
Dim i As Long

Dim sb As New StringBuilder

sb.Add("Ciao world")
sb.Add("Ciao world")

Dim s As String * 4 At sb.DataPtr

PrintL s
Long pointer
pointer = sb.DataPtr
String st
For i=1 To 20
st = Peek$(pointer, i)
PrintL st
Next


WaitKey

Petr Schreiber
12-04-2017, 23:30
Hi Primo,

perfectly valid, but this explicit length check is more safe:


Uses "StringBuilder", "Console"

Dim sb As New StringBuilder

sb.Add("Ciao world")
sb.Add("Ciao world")

Dim s As String * 4 At sb.DataPtr

PrintL s
printl

Long pointer
pointer = sb.DataPtr
String st
long i


For i=1 To sb.Length
st = Peek$(pointer, i)
PrintL st
Next

WaitKey


With this in mind, it is natural that you can reach the string inside like:


Uses "StringBuilder", "Console"

Dim sb As New StringBuilder

sb.Add("Ciao world")
sb.Add("Ciao world")

Dim s As String * sb.Length At sb.DataPtr

PrintL s

WaitKey



Petr

primo
24-07-2017, 13:55
Hi Petr
you said in the announcement of TB 1.10.1 http://www.thinbasic.com/community/showthread.php?12778-thinBasic-1-10-x&p=93686&viewfull=1#post93686
that StringBuilder can be correctly initialized via string
what does that mean ?
you already have posted above how to initialize a StringBuilder

Dim sb As New StringBuilder
sb.Add("Ciao world")
sb.Add("Ciao world")
Dim s As String * sb.Length At sb.DataPtr
PrintL s

Petr Schreiber
24-07-2017, 14:15
Hi primo,

I meant that you can do:


Dim sb As New StringBuilder("Ciao")


It will set initial text plus set internal capacity to double of initial text length (speed optimization for further additions).


Petr