Ayende @ Rahien

My name is Oren Eini
Founder of Hibernating Rhinos LTD and RavenDB.
You can reach me by phone or email:


+972 52-548-6969

, @ Q c

Posts: 6,026 | Comments: 44,842

filter by tags archive

The truth about string concatenation performance...

time to read 1 min | 112 words

Here is a riddle, what is faster?

  • string str = "Id: " + i;
  • string str = string.Format("Id: {0}", i);
  • string str = new StringBuilder().Append("Id: ").Append(i).ToString();

If you guess StringBuilder or string.Format, you are mistaken. Over 10 million iterations, the simple "Id: " + i finished in 4.7 seconds, StringBuilder in 5.7 seconds and string.Format in 7.6 seconds.

The reason for that is that the compiler can optimize the + operator to a call to string.Concat, and it does it quite often when you have several parameters. The optimizations of StringBuilder only shows up if you have several concatenations, or if you are using it on more than a single expression.


Tom Opgenorth

The rule of thumb that I use is that if you're just concatenting two or three strings, just use the '+' operator or String.Concat.

String.Format, while slow, sure is handy.

Kevin Dente

Back in the 1.1 days, it was up 4 values that would be optimized to a call to Concat:


Don't know if that changed for 2.0 though.

Either which way, mostly a micro-optimization, though. ;)

James Kovacs

Honestly this isn't too surprising if you think about what is being done. In the first instance, it's a simple string concat, as Oren mentions. For #2, you need to parse out the {0}. I find it amazing that the perf is the same order of magnitude. For #3, you have to allocate a StringBuilder object. As I recall, the break-even for StringBuilder is about a dozen concatentations. Fewer than that and your perf is dominated by allocation of the StringBuilder object. One advantage of StringBuilder is that it reduces the number of temporary strings that have to be allocated as it maintains an internal buffer, which is grown on an as-needed basis. Remember that premature optimization is the root of all evil. Fast enough and maintainable is better than blazingly fast and cryptic, IMHO.

Chris May

I think I remember reading that somewhere around 4-8 concats it becomes more performant to use the stringbuilder.

Here is an article talking about it:


Damien Guard

The point of StringBuilder is that it's much faster when dealing with large blocks of text.


Grimace of Despair

Ha... by default, Resharper suggests string.format rewrites over concatenations.

If only the aspnet compiler or some preprocessor would translate string.formats into concatenations :P

Tommaso Caldarola

Make no sense to have

string str = new StringBuilder()

in the iteration. Usually at the end of the loop you call the ToString() of the StringBuilder object.


"...The optimizations of StringBuilder only shows up if you have several concatenations..." Right!

To elaborate:

You need a new string every iteration in the loop. As 'Tommaso Caldarola' states, StringBuilder makes more sense if you want to have one string built over the whole loop.

        StringBuilder sb = new StringBuilder();

        for (int i = 0; i < 10000000; i++)


            sb.Append("Id: ").Append(i).Append(",");


        str = sb.ToString();

And you can see the real difference! I think this loop will take ages to run for a string concatenation.


Rik Hemsley

Good old StringBuilder and its inbuilt idiot detector.

If you hear someone telling you how your concatenation of three strings should be done using StringBuilder, you know instantly they're an idiot.

Stefan Wenig

The Concat method can (and will) determine the size of the resulting string in advance, so only one allocation needs to be done. (They add one alloc by copying the whole array into another array where null gets replaced by String.Empty though.)

StringBuilder has no advance knowledge of the required result buffer size and has to reallocate each time the buffer size is exceeded. Without measuring, I don't see why StringBuilder should have better performance compared to String.Concat for larger sizes. I guess unless you guess the buffer size right and pass it to the StringBuilder ctor, the opposite should be true.

I'm also surprised that String.Format plays in the same league. I think I tested it myself once and found it to be really slow.

Oren: I don't see why String.Concat(s1,s2) should be any faster than String.opAddition(s1,s2) (except that opAddition is not defined for String). Performance advantages start with 3 arguments, i.e. String.Concat(s1,s2,s3) instead of String.opAddition (String.opAddition(s1,s2),s3).

BTW, String.Concat gets called for any number of arguments, I just tested it.


Adam Machanic

It's the KISS principle in action. Use StringBuilder in a loop or somewhere that makes sense. Use + when you just need something quick and simple. Don't try to needlessly complicate your code for the sake of performance... Why, oh why, do certain devs think that maintainability should be sacrificed for a tiny percentage of a performance gain (which, as this post points out, is usually a net loss)?

Jon Skeet

I vote for option 4:

string str = "Id: " + i.ToString();

That way it calls the Concat(string[]) method instead of Concat(object[]).This means:

1) No need to call ToString on "Id: "

2) No boxing

It only saves about 5% over the 10 million iterations, but if we're microbenchmarking we might as well go for all we can :)


Comment preview

Comments have been closed on this topic.


No future posts left, oh my!


  1. Technical observations from my wife (3):
    13 Nov 2015 - Production issues
  2. Production postmortem (13):
    13 Nov 2015 - The case of the “it is slow on that machine (only)”
  3. Speaking (5):
    09 Nov 2015 - Community talk in Kiev, Ukraine–What does it take to be a good developer
  4. Find the bug (5):
    11 Sep 2015 - The concurrent memory buster
  5. Buffer allocation strategies (3):
    09 Sep 2015 - Bad usage patterns
View all series


Main feed Feed Stats
Comments feed   Comments Feed Stats