is Stringbuilder the same as string concatenation?

cjard

Well-known member
Joined
Apr 25, 2006
Messages
7,081
Programming Experience
10+
StringBuilder comment noted, but dont worry.. VB uses it anyway..


If you compile my example, then decompile it with a simplistic decompiler you'll get:

String s = New StringBuilder("hello").Append(myVariable).Append("world").ToString()

So dont worry.. StringBuilder is used every time you concatenate a string - you just dont see it because it goes into the IL. Your point of explicitly using one is valid though, as you can preset known capacities and re-use it to save creation of stringBuilder objects all the time.

I originally posted because I wanted to comment out a argument in a method:

VB.NET:
mySub( p1, _
       p2, _
       Nothing, _ 'p3, _
       p4 _
)

its just it was easier to write a string example than paste the method in, which is significantly more messy. Glad the debate arose though, cause some good points always come out of them - in a way, i never mind threads that go OT once the original question is answered, because more knowledge is spread as a result..
 
Something must have changed then, because previously it was stated that it didn't.... and that everytime you do a concat on a string, it had to make new copy (rather than appending to the memory location) thus making it inefficient for large strings.... Will investigate further...

-tg
 
I knew it was in there somewhere:
FROM MSDN said:
A string is a sequential collection of Unicode characters, typically used to represent text, while a String is a sequential collection of System.Char objects that represents a string. The value of the String is the content of the sequential collection, and the value is immutable.

A String is called immutable because its value cannot be modified once it has been created. Methods that appear to modify a String actually return a new String containing the modification. If it is necessary to modify the actual contents of a string-like object, use the System.Text.StringBuilder class.
source: http://msdn.microsoft.com/library/d...us/cpref/html/frlrfsystemstringclasstopic.asp

Which makes sense, given the code you showed, where it created a new string object.... where as, if you use the StringBuilder yourself directly, and new object does not get created.
So, while it is using StringBuilder on the back end, it's HOW it gets used that seems to be the difference.

Not that I have ever dealt with something so large that a simple concat wouldn't work...
-tg
 
TechGnome said:
Something must have changed then, because previously it was stated that it didn't.... and that everytime you do a concat on a string, it had to make new copy (rather than appending to the memory location) thus making it inefficient for large strings.... Will investigate further...

-tg

Nothing has changed, strings are still immutable and they arent appended to. :)

Just a clarification for others who might still be a bit confused by the concept.. I'm not claiming that strings are stored in stringbuilders and manipulated when we say "hello" & "world".. if we look at my code, I simply show how a string is appended to. For example:

String s = "hello"
String t = s & "world"

is turned into this by the compiler. You never see this, but its an easy way strings can be concatted in a language that has immutable strings:

String s = "hello"
String t = New StringBuilder(s).Append("world").ToString()

note the .tostring call - its very important because it turns the contents of the stringbuilder into a string by creation of a new string object which is then referenced by t

The stringbuilder is thrown away when it has done its job (it's anonymous).. So why does the compiler use it? well... StringBuilder is provided for us as a utility class by MS, to build strings.. And given that it has a simple usage pattern, the compiler can use it too, applying this pattern every time it finds a string being concatted:

String z = a & b & c & d

can be turned into this with some funky regex style find and replace:

String z = New StringBuilder(a).Append(b).Append(c).Append(d).ToString()


The functions are run left to right. Each returns the same stringbuilder that was jsut modified, so after 4 successive mods, our stringbuilder holds the new value we want to put in Z. Its far easier to do this (regex style find and replace) in a programming language, than it is to write a special chunk of code that handles & operator for strings in memory.

In a similar way, I could expect two ints I and J when added and assigned to another to be presented like this:

int k = ji + j
int k = New Integer(i).Add(j).ToInteger()


I doubt this level of complexity is implemented for the primitive types, but string is not a primitive even though we treat it as such often.. :)
 
TechGnome said:
So, while it is using StringBuilder on the back end, it's HOW it gets used that seems to be the difference.

Oh absolutely.. We tend to declare stringbuilders like this:

Dim sb as New StringBuilder


And then use the sb reference repeatedly over the next few lines of code, and finally say .ToString() to make a string out of it


Its perfectly logical code however, to do it all in one line, and indeed its the very reason that Append() returns the modified stringbuilder - so it can be used anonymously sequentially



Moving to another example. Suppose we were using a database parameter object that every method returned the updated parameter. We could logically say:

MyCommand.Parameters.Add(New Parameter("column name").SetType("var char").SetValue("hey there").SetDirection(Input))

All these Set() methods return the parameter with "Return Me" as the function return path; we make a new param, setting the column name in the constructor. the new param is returned from the constructor (which after all is jsut a special function that returns Me at the end of it) and we can call SetType, which returns me, and we call Set... which returns Me and finally the parameter is added to the collection (which then keeps a reference to it so it isnt garbage collected)

Nifty huh?

Of course we are far more likely to ignore the return values and say:

Dim x as New Parameter("name")
x.SetType("type")
x.SetValue("val")
Command.Parameters.Add(x)


but there isnt any real need to and a lot of the auto genned code by the wizards and the designer, will make objects anonymously, use them, set things, get a return val and throw the object away all in one line
 
Back
Top