Check my code: StringBuilder vs. concatenation

I think I did this right, but give it a look. I'm trying to demonstrate the benefit of using StringBuilder over straight string concatenation. The two loops are functionally equivalent, right?

string sentence = "I really like riding roller coasters because they're super fun and have ups and downs, just like life!";
string[] words = sentence.Split(new char[] { ' ' });
string result = "";
Trace.Warn("Start concatenation");
for (int i = 0; i < 1000; i++)
{
 foreach (string word in words)
 {
  result = result + word + " ";
 }
}
Trace.Warn("End concatenation");
Trace.Warn("Start StringBuilder");
StringBuilder builder = new StringBuilder();
for (int i = 0; i < 1000; i++)
{
 foreach (string word in words)
 {
  builder.Append(word);
  builder.Append(" ");
 }
}
result = builder.ToString();
Trace.Warn("End StringBuilder");

If you're interested, the trace times looked like this:

Start concatenation 0.000157
End concatenation 22.377516
Start StringBuilder 0.000212
End StringBuilder 0.013082

10 Comments

  • Looks good to me. Stringbuilder kicks ass, doesn't it? :)

  • I'm more curious about AppendFormat(). How big of a hit does that take out of the works?



    For example:



    builder.AppendFormat(&quot;{0} \n&quot;, word);

  • well, APpendFormat is obviously using String.Format under the hood, so there's a cost factor involved in tokenizing the &quot;Format string&quot; and inserting the values into the resulting string [which ironically uses StringBuilder itself! go figure... kinda like Alabama cousins]



    Supposedly you can also use a string[] to build a set of strings, typically staggered as literal/changable/literal/changable etc and it's even faster than stringbuilder:



    &lt;code&gt;

    string[] full = new string[1000];

    string[] test = new string[5];

    for(int i=0; i &lt;= 1000; i++)

    for( int j=0; j &lt;= 1000; j++ )

    {

    test[0] = &quot;The current value of I is &quot;;

    test[1] = i.ToString();

    test[2] = &quot;. The current value of J is &quot;;

    test[3] = j.ToString();

    test[4] = &quot;.\n&quot;;

    }

    full[i] = string.Concat(test);

    }

    Console.WriteLine(string.Concat(full));

    &lt;/code&gt;

  • In Java World there used to be huge debates whether to use string concatenation or StringBuffer class. Currently as Java compilers have got more mature these conversations doesn't arise as often as they used to. And, yes you get same performance with both techniques. Java Compilers replace repetive string concatenations with string buffers. I see no reason why this feature has not been implemented in .NET. If you ask me, StringBuffers have no use if you have compiler smart enough to deal with this issue.

  • Jeff - works great if you have a developer that is actually going to append 1000 strings on different lines of code (hopefully even the slightest code review would catch that). If you have a lot of concatenations using the + command you will see using reflector that only 1 concat is called under the hood.



    At some point in time the overhead of StringBuilder outweighs its usefulness. That is the point around which guidance need be given. I've heard somewhere around 5-10 concats is where StringBuilder gains enough of an advantage to use it. Your mileage may vary.

  • I can't agree more with Darrell.



    A lot of the &quot;religious&quot; wars have to do with performance. We always here - don't use dynamic SQL, use stored procedures. Don't use foreach, use a for loop. Don't concatenate, use StringBuilder. Don't use the DataSet, use the DataReader. Don't access DataRow fields by column name, access them by index, don't use O/R Mappers, build your own data layer, etc., etc., etc.



    Certainly it is important to know the trade-offs in performance when building the application, but it is important to know at what point one actually sees a performance hit and understand that the performance hit may be acceptable from a maintainability and cost standpoint.



    Not every website is Match.com. Not every application is SAP.



    You seem like a very pragmatic developer, so I suspect you will touch on those areas of reality when appropriate.

  • Try...



    string.Join(&quot; &quot;,words) instead of the inner loop. Might be even faster :)

  • To be even more dramatic (and line by line code equivalent):



    result = result + word + &quot; &quot;;



    should read



    result = result + word;

    result = result + &quot; &quot;;



    It's not fair to optimize the &quot;bad&quot; code! After all, the StringBuilder has to do it in two lines!



    With my proposed change:



    Before:

    00:00:17.9078928

    00:00:00.0100156



    After

    00:00:35.7356608

    00:00:00.0100156

  • However:

    string f = &quot;Foo&quot;;

    string b = &quot;Bla&quot;;

    string s = f + b;

    beats:

    StringBuilder sb = new StringBuilder();

    sb.AppendFormat(&quot;{0}{1}&quot;, f, b);



    Stringbuilder is not always 'the right way' ;)

  • thanks
    i got a good idea

Comments have been disabled for this content.