1

Here is 2 methods which result the same:

public class MessageManager
{
    public void SendMessage(string name, int count)
    {
        string message = "Hi " + name + ". I know you don't like cake, so I bought you " + count + " lollipops. Same thing, right?"; // No boxing. "count" was converted to string somehow.
        //Console.WriteLine(message);
    }
    public void SendMessage2(string name, int count)
    {
        string message = String.Format("Hi {0}. I know you don't like cake, so I bought you {1} lollipops. Same thing, right?", name, count); // Boxing "name" and "count" + executing unnecessary code.
        //Console.WriteLine(message);
    }
}

So I guess the second method will be slower then first because of boxing and executing some additional code which inside String.Format() method.

I have tested them with following method:

public static class PerformanceTester
{
    public static TimeSpan TestAction(Action<string, int> action)
    {
        Stopwatch timer = new Stopwatch();
        timer.Start();
        for (ushort i = 0; i < ushort.MaxValue; i++)
            action("Alex", 1000);
        timer.Stop();
        return timer.Elapsed;
    }
}

And here is the usage of it:

    static void Main(string[] args)
    {
        MessageManager mm = new MessageManager();

        TimeSpan ts_m1 = PerformanceTester.TestAction(new Action<string, int>(mm.SendMessage));
        TimeSpan ts_m2 = PerformanceTester.TestAction(new Action<string, int>(mm.SendMessage2));

        Console.WriteLine("First message took time: " + ts_m1.ToString());
        Console.WriteLine("Second message took time: " + ts_m2.ToString());

        Console.ReadKey();
    }

Output with my Intel® Core™2 Duo Processor E8200 (DEBUG):

string_test

Output with my Intel® Core™2 Duo Processor E8200 (RELEASE): enter image description here

I saw String.Format used almost everywhere (guides, blogs, tutorials etc.) but it is actually slower than simple string concatenation. I know when I talk about C# I must not care about performance, but the results in this example is too awesome. The question is: "Is there any best practice where String.Format is actually better than concatenation of strings."

Wallstrider
  • 856
  • 1
  • 7
  • 22
  • Is it a release build? If so, won't csc optimize it and remove the code that doesn't have any side effects at all? – zerkms Apr 07 '14 at 02:54
  • String concatenation is the fastest but consumes bit of memory. String.format code is hard to read (if you consider code readability). It's actually what you want to achieve. You'll have to compromise one for the other. There's a good discussion here http://www.michaelmerrell.com/2011/11/string-format-versus-string-concatenation-vs-stringbuilder/ – Sam Apr 07 '14 at 02:58
  • @zerkms it is debug. I added release as well now. – Wallstrider Apr 07 '14 at 03:02
  • @Pierre-LucPineault Cannot find answer on my question there. The question is: "Is there any best practice where String.Format is actually better than concatenation of strings." – Wallstrider Apr 07 '14 at 03:09
  • @Wallstrider if you want best practices, use [Code Review](http://codereview.stackexchange.com/). – Pierre-Luc Pineault Apr 07 '14 at 03:10
  • Where's Jon Skeet when you need him... he did an awesome explanation of this in one of the videos on Plurasight. Hopefully he notices this post. – B.K. Apr 07 '14 at 03:26
  • There's no boxing involved if the parameters are not value types. And in this case, `name` is not boxed. It also matters if you ran them with the debugger attached. The only timings that have meaning are those run with a Release build and no debugger attached (i.e. "Start without debugging", or Ctrl+F5). – Jim Mischel Apr 07 '14 at 03:28
  • *I know when I talk about C# I must not care about performance.* Really? What gives you that idea? – Jim Mischel Apr 07 '14 at 03:33
  • @JimMischel because most people is referencing to C++ when talk about performance. :)) – Wallstrider Apr 07 '14 at 11:45

2 Answers2

3

It's largely a matter of style. However, consider more complex formatting. For example you want to format a bunch of stuff:

var s = String.Format("{0,10:N2}  {1,-20}  {2:P2}", val, description, (val/100));

Or ...

var s = val.ToString("10:N2") + string.Format("{0,-20}", desc) + (val/100).ToString("P2");

I like the String.Format call there much better. It separates the formatting from the content in much the way that CSS separates the presentation from the HTML content. When I'm writing or examining code that formats output, I typically want to see the format at a glance. The actual values being formatted aren't relevant when I'm debugging a formatting issue.

With concatenation, I have to slog my way through the individual values to see what the format is for each item.

Finally, does performance really matter here? Most programs spend precious little time formatting their output. Optimizing the formatting code seems like a huge waste of time. Write whatever is easier to maintain and prove correct.

Jim Mischel
  • 131,090
  • 20
  • 188
  • 351
2

string.format is as the name suggest for formatting strings. you can take the format string and stick it in a resource or have it translated. it is not about performance and it is not about readability. simple string concatenation is ok if you do let's say less than 5. if you want to concatenate more strings and want to consider the performance - use StringBuilder.

Z .
  • 12,657
  • 1
  • 31
  • 56
  • 1
    I think you'll find that compile time concatenation expressions like those the OP shows are resolved to calls to `String.Concat`, which "does the right thing." Internally, it uses a `StringBuilder`. See the reference source for [String.Concat](http://referencesource.microsoft.com/#mscorlib/system/string.cs#206408f6325aea24) – Jim Mischel Apr 07 '14 at 03:24
  • +1 for the translation comment. Something I hadn't considered. – Jim Mischel Apr 07 '14 at 03:34
  • @JimMischel thanks for the link. Didn't know that the source of the framework exists. – Wallstrider Apr 07 '14 at 11:48