09 March, 2011

String to StringBuilder conversion - a pitfall

If you've known that the way to go is by using StringBuilder instead of String, due to its memory use advantage, beware.

The coder's ease in using String isn't quite as straightforward when it comes to StringBuilder.

Below is one example where the code change is non-glaring, but the impact can be disastrous.


    Dim myStringBfr As String = ""

    myStringBfr += ""
    myStringBfr += "Some text to go here. "
    myStringBfr += "Some more text to go here. "
    myStringBfr += "Final text string to be added goes here. " & vbCrLf
    myStringBfr = myStringBfr + " - string concatenation ends here - "

    Console.WriteLine()

    Console.WriteLine(myStringBfr)


Common conversion happens this way (at least for my case)
  1. Change in declaration
  2. Change in assignments
  3. Change in method calls

    Dim myStringBldrBfr As New StringBuilder

    myStringBldrBfr.Append("")
    myStringBldrBfr.Append("Some text to go here. ")
    myStringBldrBfr.Append("Some more text to go here. ")
    myStringBldrBfr.Append("Final text string to be added goes here. ").AppendLine()
    myStringBldrBfr.Append(myStringBldrBfr).Append(" - string concatenation ends here - ")

    Console.WriteLine()

    Console.WriteLine(myStringBldrBfr.ToString())
    'Console.WriteLine(myStringBldrBfr) also works


When you try to run this very simple demo by creating a console application and typing in these few lines, the output will be like below:


"
Some text to go here. Some more text to go here. Final text string to be added goes here.
 - string concatenation ends here -

Some text to go here. Some more text to go here. Final text string to be added goes here.
Some text to go here. Some more text to go here. Final text string to be added goes here.
 - string concatenation ends here -
Press any key to continue . . .
"

Suggestions:

Avoid the Double Append call:
myStringBldrBfr.Append(myStringBldrBfr).Append("...
should be written as
myStringBldrBfr.Append("...

Reset or initialize the StringBuilder var
Instead of doing myStringBldrBfr.Append(""), set the length to zero.
myStringBldrBfr.Length = 0

As much as possible, define and use a local-scope variable. when it cannot be avoided, or that the overall impact of using StringBuilder is significant, then define and use a global-scope var.

This is especially true if you are using your SB var in a loop. Make sure that once the SB var is used, set the length to zero (0) to clear its contents, or the value is simply carried over and over again, the impact of which who knows?


Below is the corrected code, and the output is the same as when you used String:


    Dim myStringBldrBfrFin As New StringBuilder

    myStringBldrBfrFin.Append("Some text to go here. ")
    myStringBldrBfrFin.Append("Some more text to go here. ")
    myStringBldrBfrFin.Append("Final text string to be added goes here. ").AppendLine()
    myStringBldrBfrFin.Append(" - string concatenation ends here - ")

    Console.WriteLine()

    Console.WriteLine(myStringBldrBfrFin.ToString())
    myStringBldrBfrFin.Length = 0



Hope this code nugget is of help to those who need it most.
Till then!


Enhanced by Zemanta