You need to process many pieces of string data with more efficiency than is allowed using standard .NET Framework immutable strings.
The StringBuilder object provides extremely fast and efficient in-place processing of string and character data. The following code demonstrates several of its powerful methods and some of the techniques you can use to speed up your string processing:
Dim workText As New System.Text.StringBuilder ' ----- Build a basic text block. workText.Append("The important") workText.Append(vbNewLine) workText.Append("thing is not") workText.AppendLine() workText.AppendLine("to stop questioning.") workText. Append("--Albert Einstein") MsgBox(workText.ToString( )) ' ----- Delete the trailing text. Dim endSize As Integer = "--Albert Einstein".Length workText.Remove(workText.Length - endSize, endSize) MsgBox(workText.ToString( )) ' ----- Modify text in the middle. workText.Insert(4, "very ") MsgBox(workText.ToString( )) ' ----- Perform a search and replace. workText.Replace("not", "never") MsgBox(workText.ToString( )) ' ----- Truncate the existing text. workText.Length = 3 MsgBox(workText.ToString( ))
The first line of the previous code creates a new instance of the StringBuilder object. The next half dozen or so lines of code show various common uses of the StringBuilder's Append() and AppendLine() methods. Each call to Append() or AppendLine() concatenates another string or character piece into the StringBuilder's buffer. Figure 5-1 shows the result of these first few append actions.
Figure 5-1. Piecing together strings with the StringBuilder
Avoid the temptation to concatenate these string pieces using the & operator as you prepare the various pieces for appending to the StringBuilder. Doing so detracts from the efficiency and speed advantages of the StringBuilder. For example, both of the following lines of code are legal and correct, but the line that uses the & operator does a lot more work behind the scenes:
' ----- Don't do this! workText.Append("This " & "is " & "not advisable!") ' ----- Please do this. workText.Append("This ").Append("is ").Append("faster!")
The first statement (the one using the & operator) must make working copies of the immutable strings to do the concatenations. Timing tests demonstrate that this can slow down your code measurably.
Besides Append(), the StringBuilder object also provides methods that parallel other functions available for processing true strings. These include Remove(), Replace(), and Insert() methods, as demonstrated in the sample code presented earlier in this recipe. The Length property shown in the sample is also available as a standard property of strings. The remaining lines of code in the sample demonstrate the use of these methods by modifying parts of the original quote.
A StringBuilder's contents are technically not a string. Rather, the StringBuilder maintains an internal buffer of characters that at any time can easily be converted to a string using the StringBuilder's ToString() method. Think of a StringBuilder as a string in the making that's not really a string until you want it to be.
Behind the scenes, the default StringBuilder's buffer starts out with a working space, or capacity, of only 16 bytes. The buffer automatically doubles in size whenever it needs more space, jumping to 32 bytes, then 64, and so on. If you have a good idea how much space your string processing may require, you can initialize StringBuilder's buffer to a given capacity during the declaration. For example, this declaration creates a StringBuilder instance with a preallocated buffer size of 1,000 bytes:
Dim workText As New System.Text.StringBuilder(1000)
The advantage of providing the starting capacity is a potential performance boost. In this case, the buffer's workspace won't need to be doubled until enough strings have been appended to overflow the 1,000-byte limit.
You can access the StringBuilder's capacity at runtime through its Capacity property. It's enlightening to read this property to follow along as the StringBuilder doubles in size during execution. You can set the Capacity to a new value at any time, but if you set the Capacity to less than the StringBuilder's current Length, an exception occurs. If your intent is to shorten, or truncate, the contents of the buffer, set the Length property instead, and leave Capacity alone. The easiest way to empty a StringBuilder of its contents is to set its Length property to zero.
Recipe 5.26 also discusses building up strings from smaller components.