One of the common criticisms levelled at me from certain types of developers
(a type which really needs its own name) is that when I’m building a large
string, I don’t always use StringBuilder. For example, when I’m building an
SQL statement, I simply concatenate the lines of the statement using the
& operator. For example:
Command.CommandText = _
( _
"INSERT INTO [PrintMargins]" _
& " (" _
& " [PrinterName]," _
& " [LeftMargin]," _
& " [RightMargin]," _
& " [TopMargin]," _
& " [BottomMargin]" _
& " )" _
& " VALUES" _
& " (" _
& " @PrinterName," _
& " @LeftMargin," _
& " @RightMargin," _
& " @TopMargin," _
& " @BottomMargin" _
& " )" _
)
Command.Parameters.Add("@PrinterName", PrinterName)
Command.Parameters.Add("@LeftMargin", Margins.Left)
etc.
Unless a profiler showed me that this code was causing a bottleneck due to the building of the string taking a great deal of time, there’s no way I would even have considered using a StringBuilder here.
The likelihood that a few (about 15?) string concatenations would be anywhere near significant in the time taken to perform this operation on the RDBMS just seems incredibly low to me, based on my experience with various other platforms and languages.
I would also guess that the compiler might take a pair of string constants with the ‘&’ operator between them and simply concatenate them at compile time, though I wouldn’t assume so.
Of course, as a humble developer, I’m always willing to bow to the measurements of the profiler and, having worked with Microsoft’s development products for some time, would not have been too shocked to learn that a bug (sorry, ‘by-design feature’) in the compiler would cause concatenations like the above to eat several seconds of CPU. As a developer, you can’t make too many assumptions.
I was taken to task for just this kind of concatenation (constant strings). So I benchmarked it.
Function TestConcat As String
Dim Lyrics As String = "Shower in the dark day" _
& "Clean sparks diving down" _
& "Cool in the waterway" _
& "Where the baptised drown" _
& "Naked in the cold sun" _
& "Breathing life like fire" _
& "Thought I was the only one" _
& "But that was just a lie" _
& "Heard it in the wind" _
& "Saw it in the sky" _
& "Thought it was the end" _
& "Thought it was fourth of July" _
Return Lyrics
End Function
Function TestStringBuilder As String
Dim LyricsBuilder As New StringBuilder("Shower in the dark day")
LyricsBuilder.Append("Clean sparks diving down")
LyricsBuilder.Append("Cool in the waterway")
LyricsBuilder.Append("Where the baptised drown")
LyricsBuilder.Append("Naked in the cold sun")
LyricsBuilder.Append("Breathing life like fire")
LyricsBuilder.Append("Thought I was the only one")
LyricsBuilder.Append("But that was just a lie")
LyricsBuilder.Append("Heard it in the wind")
LyricsBuilder.Append("Saw it in the sky")
LyricsBuilder.Append("Thought it was the end")
LyricsBuilder.Append("Thought it was fourth of July")
Return LyricsBuilder.ToString()
End Function
Sub Main
Dim Start As DateTime
Const Iterations As Integer = 10000000
Start = DateTime.Now
For i As Integer = 1 To Iterations: TestConcat: Next i
Console.WriteLine(DateTime.Now.Subtract(Start).TotalMilliseconds.ToString)
Start = DateTime.Now
For i As Integer = 1 To Iterations : TestStringBuilder: Next i
Console.WriteLine(DateTime.Now.Subtract(Start).TotalMilliseconds.ToString)
Console.ReadLine
End Sub
Results with debugging on:
78.1265
19484.7491
Results with debugging off:
0
19344.1214
The compiler may have optimised away my calls to TestConcat when debugging was off, but I think it’s pretty obvious that using StringBuilder in this situation does not speed up the code.
There’s an article here measuring the performance of StringBuilder as compared to concatenation - where the strings are concatenated in a loop - and the compiler can’t optimise away that concatenation. I measured this myself some time ago and came to the same conclusion.