views:

420

answers:

9

Are there differences between these examples? Which should I use in which case?

var str1 = "abc" + dynamicString + dynamicString2;

var str2 = String.Format("abc{0}{1}", dynamicString, dynamicString2);

var str3 = new StringBuilder("abc").Append(dynamicString).Append(dynamicString2).ToString();

var str4 = String.Concat("abc", dynamicString, dynamicString2);

There are similar questions:

This question is asking about what happens in each case, what will be the real output of those examples? What are the differences about them? Where should I use them in which case?

+13  A: 

As long as you are not deailing with very many (100+) strings or with very large (Length > 10000) strings, the only criterion is readability.

For problems of this size, use the +. That + overload was added to the string class for readability.

Use string.Format() for more complicated compositions and when substitutions or formatting are required.

Use a StringBuilder when combining many pieces (hundreds or more) or very large pieces (length >> 1000). StringBuilder has no readability features, it's just there for performance.

Henk Holterman
It may also be worth considering the size of the strings being concatenated. If you were to say concatenate 10 huge strings it would be worth it to use a `StringBuilder`.
ChaosPandion
@Chaos: Right, but they would have to be really big and handling those would be a separate topic
Henk Holterman
@Henk - I just wanted to chime in with a semi-intelligent comment. Helps get me through the day. :)
ChaosPandion
@Chaos, I got that, and I said you were right. I sometimes come across the notion that 100 chars is 'big' and anything over 1000 chars is 'huge'. In answers, we should add ballpark numbers to such adjectives. My error too, I edited a little.
Henk Holterman
@Henk - You make a lot of sense. Oftentimes I'll take for granted my general knowledge around other programmers. I will be working harder to be more explicit. Also your answer is way better than the accepted one in the duplicate question.
ChaosPandion
+2  A: 

My rule of thumb is to use String.Format if you are doing a relatively small amount of concatination (<100) and StringBuilder for times where the concatination is going to be large or is potentially going to be large. I use String.Join if I have an array and there isn't any formatting needed.

You can also use the Aggregate function in LINQ if you have an enumerable collection: http://msdn.microsoft.com/en-us/library/bb548651.aspx

Jerod Houghtelling
@Xander just pointed out that String.Format uses a StringBuilder beneath the service. If that's true then I guess String.Fromat vs StringBuilder is a horrible comparison. In that case you might be better off doing the concatenation with '+=' if you aren't going to trash memory too bad.
Jerod Houghtelling
are you Xander's attorney? if someone point towards grand canion and says - Jump.. are you going to jump?
Bobb
+1  A: 

@ Jerod Houghtelling Answer

Actually String.Format uses a StringBuilder behind the scenes (use reflecton on String.Format if you want)

I agree with the following answer in general

Xander
Does the `+` operator use StringBuilder as well?
BrunoLM
what? are you sure? I did test betweem string.format and sb.append and sb kicked arse.... I think your reflector was drunk at that moment
Bobb
@BrunoLM: No, a string is immutable, so when you use the + operator, you actually receive a new string instance.
JohnForDummies
@Bobb it actually creates a `new StringBuilder`, append the strings, apply the `format` and return the sb.ToString()
BrunoLM
@BrunoLM - Yes that is the case, String.Format is doing more work hence why its a little slower than using StringBuilder directly.
Xander
+4  A: 

Use the + operator in your scenario.

I would only use the String.Format() method when you have a mix of variable and static data to hold in your string. For example:

string result=String.Format("Today {0} scored {1} {2} and {3} points against {4}",..);
//looks nicer than
string result = "Today " + playerName + " scored " + goalCount + " " + scoreType + " and " + pointCount + " against " + opposingTeam;

I don't see the point of using a StringBuilder, since you're already dealing with three string literals.

I personally only use Concat when dealing with a String array.

baultista
A: 
var str3 = new StringBuilder.AppendFormat("abc{0}{1}", dynamicString, dynamicString2).ToString(); 

the code above is the fastest. so use if you want it fast. use anything else if you dont care.

Bobb
String.Format() uses a StringBuilder behind the scenes, so this is no better.
Joel Coehoorn
+1  A: 

@Xander. I believe you man. However my code shows sb is faster than string.format.

beat this:

        Stopwatch sw = new Stopwatch();
        sw.Start();

        for (int i = 0; i < 10000; i++)
        {
            string r = string.Format("ABC{0}{1}{2}", i, i-10, "dasdkadlkdjakdljadlkjdlkadjalkdj");
        }

        sw.Stop();
        Console.WriteLine("string.format: " + sw.ElapsedTicks);

        sw.Reset();
        sw.Start();
        for (int i = 0; i < 10000; i++)
        {
            StringBuilder sb = new StringBuilder();
            string r = sb.AppendFormat("ABC{0}{1}{2}", i, i - 10, "dasdkadlkdjakdljadlkjdlkadjalkdj").ToString();
        }

        sw.Stop();
        Console.WriteLine("AppendFormat: " + sw.ElapsedTicks);
Bobb
I did also comparison a while ago - there is even faster solution -when you create SB once in a class life time and then just use sb.Clear before sb.AppendFormat.
Bobb
The only difference between them is that `String.Format` instantiate the StringBuilder like this `StringBuilder builder = new StringBuilder(format.Length + (args.Length * 8));` and has a parameter validation. That might be the cause of the small difference.
BrunoLM
Also - use StartNew() rather than reset/start.
Joel Coehoorn
the code was written in vs2008. there is no start new
Bobb
@Bruno - if you do few millions operations a day like that - believe me - I do - the difference is not small.
Bobb
Yes, I agreed. But a situation like that is unlikely. But anyway, using directly StringBuilder is faster than String.Format, there is no doubt.
BrunoLM
+4  A: 

Gathering information from all the answers it turns out to behave like this:

The + operator is the same as the String.Concat, this could be used on small concatenations outside a loop, can be used on small tasks.

In compilation time, the + operator generate a single string if they are static, while the String.Concat generates the expression str = str1 + str2; even if they are static.

String.Format is the same as StringBuilder.. (example 3) except that the String.Format does a validation of params and instantiate the internal StringBuilder with the length of the parameters.

String.Format should be used when format string is needed, and to concat simple strings.

StringBuilder should be used when you need to concatenate big strings or in a loop.

BrunoLM
A: 

It's important to understand that strings are immutable, they don't change. So ANY time that you change, add, modify, or whatever a string - it is going to create a new 'version' of the string in memory, then give the old version up for garbage collection. So something like this:

string output = firstName.ToUpper().ToLower() + "test";

This is going to create a string (for output), then create THREE other strings in memory (one for: ToUpper(), ToLower()'s output, and then one for the concatenation of "test").

So unless you use StringBuilder or string.Format, anything else you do is going to create extra instances of your string in memory. This is of course an issue inside of a loop where you could end up with hundreds or thousands of extra strings. Hope that helps

Robert Seder
A: 

It is important to remember that strings do not behave like regular objets. Take the following code:

string s3 = "Hello ";
string s3 += "World";

This piece of code will create a new string on the heap and place "Hello" into it. Your string object on the stack will then point to it (just like a regular object).

Line 2 will then creatre a second string on the heap "Hello World" and point the object on the stack to it. The initial stack allocation still stands until the garbage collector is called.

So....if you have a load of these calls before the garbage collector is called you could be wasting a lot of memory.

Shane