views:

778

answers:

6

Someone told me that it's faster to concatenate strings with StringBuilder. I have changed my code but I do not see any Properties or Methods to get the final build string.

How can I get the string?

+5  A: 

Once you have completed the processing using the StringBuilder, use the ToString method to return the final result.

From MSDN:

using System;
using System.Text;

public sealed class App 
{
    static void Main() 
    {
        // Create a StringBuilder that expects to hold 50 characters.
        // Initialize the StringBuilder with "ABC".
        StringBuilder sb = new StringBuilder("ABC", 50);

        // Append three characters (D, E, and F) to the end of the StringBuilder.
        sb.Append(new char[] { 'D', 'E', 'F' });

        // Append a format string to the end of the StringBuilder.
        sb.AppendFormat("GHI{0}{1}", 'J', 'k');

        // Display the number of characters in the StringBuilder and its string.
        Console.WriteLine("{0} chars: {1}", sb.Length, sb.ToString());

        // Insert a string at the beginning of the StringBuilder.
        sb.Insert(0, "Alphabet: ");

        // Replace all lowercase k's with uppercase K's.
        sb.Replace('k', 'K');

        // Display the number of characters in the StringBuilder and its string.
        Console.WriteLine("{0} chars: {1}", sb.Length, sb.ToString());
    }
}

// This code produces the following output.
//
// 11 chars: ABCDEFGHIJk
// 21 chars: Alphabet: ABCDEFGHIJK
BlackWasp
+19  A: 

You can use .ToString() to get the String from the StringBuilder.

Daok
+2  A: 

I would just like to throw out that is may not necessarily faster, it will definitely have a better memory footprint. This is because string are immutable in .NET and every time you change a string you have created a new one.

smaclell
+1  A: 

It's not faster to concat - As smaclell pointed out, the issue is the immutable string forcing an extra allocation and recopying of existing data.

"a"+"b"+"c" is no faster to do with string builder, but repeated concats with an intermediate string gets faster and faster as the # of concat's gets larger like:

x = "a"; x+="b"; x+="c"; ...

Tony Lee
A: 

About it being faster/better memory:

I looked into this issue with Java, I assume .NET would be as smart about it.

The implementation for String is pretty impressive.

The String object tracks "length" and "shared" (independent of the length of the array that holds the string)

So something like

String a="abc" + "def" + "ghi";

can be implemented (by the compiler/runtime) as:

 - Extend the array holding "abc" by 6 additional spaces.
 - Copy def in right after abc 
 - copy ghi in after def. 
 - give a pointer to the "abc" string to a 
 - leave abc's length at 3, set a's length to 9
 - set the shared flag in both.

Since most strings are short-lived, this makes for some VERY efficient code in many cases. The case where it's absolutely NOT efficient is when you are adding to a string within a loop, or when your code is like this:

a="abc";
a=a+"def";
a+="ghi"; 

In this case, you are much better off using a StringBuilder construct.

My point is that you should be careful whenever you optimize, unless you are ABSOLUTELY sure that you know what you are doing, AND you are absolutely sure it's necessary, AND you test to ensure the optimized code makes a use case pass, just code it in the most readable way possible and don't try to out-think the compiler.

I wasted 3 days messing with strings, caching/reusing string-builders and testing speed before I looked at the string source code and figured out that the compiler was already doing it better than I possibly could for my use case. Then I had to explain how I didn't REALLY know what I was doing, I only thought I did...

Bill K
+1  A: 

When you say "it's faster to concatenate String with a String builder", this is only true if you are repeatedly (I repeat - repeatedly) concatenating to the same object.

If you're just concatenating 2 strings and doing something with the result immediately as a string, there's no point to using StringBuilder.

I just stumbled on Jon Skeet's nice write up of this: http://www.yoda.arachsys.com/csharp/stringbuilder.html

If you are using StringBuilder, then to get the resulting string, it's just a matter of calling ToString() (unsurprisingly).

Michael Burr