<p>Suppose I have a stringbuilder in C# that does this:</p>

<pre><code>StringBuilder sb = new StringBuilder();
string cat = "cat";
sb.Append("the ").Append(cat).(" in the hat");
string s = sb.ToString();
</code></pre>

<p>would that be as efficient or any more efficient as having:</p>

<pre><code>string cat = "cat";
string s = String.Format("The {0} in the hat", cat);
</code></pre>

<p>If so, why?</p>

<p><strong>EDIT</strong> </p>

<p>After some interesting answers, I realised I probably should have been a little clearer in what I was asking. I wasn't so much asking for which was quicker at concatenating a string, but which is quicker at <strong><em>injecting</em></strong> one string into another.</p>

<p>In both cases above I want to inject one or more strings into the middle of a predefined template string.</p>

<p>Sorry for the confusion</p>

[{'answer_id': 6786, 'author': 'GateKiller', 'author_id': 383, 'author_profile': 'https://Stackoverflow.com/users/383', 'pm_score': -1, 'selected': False, 'text': '<p>I would suggest not, since String.Format was not designed for concatenation, it was design for formatting the output of various inputs such as a date.</p>\n\n<pre><code>String s = String.Format("Today is {0:dd-MMM-yyyy}.", DateTime.Today);\n</code></pre>\n'}, {'answer_id': 6788, 'author': 'Joseph Daigle', 'author_id': 507, 'author_profile': 'https://Stackoverflow.com/users/507', 'pm_score': 0, 'selected': False, 'text': '<p>It really depends. For small strings with few concatenations, it\'s actually faster just to append the strings.</p>\n\n<pre><code>String s = "String A" + "String B";\n</code></pre>\n\n<p>But for larger string (very very large strings), it\'s then more efficient to use StringBuilder.</p>\n'}, {'answer_id': 6789, 'author': 'Greg', 'author_id': 108, 'author_profile': 'https://Stackoverflow.com/users/108', 'pm_score': 6, 'selected': False, 'text': '<p>From the <a href="http://msdn.microsoft.com/en-us/library/system.text.stringbuilder.aspx" rel="noreferrer">MSDN documentation</a>:</p>\n\n<blockquote>\n  <p>The performance of a concatenation operation for a String or StringBuilder object depends on how often a memory allocation occurs. A String concatenation operation always allocates memory, whereas a StringBuilder concatenation operation only allocates memory if the StringBuilder object buffer is too small to accommodate the new data. Consequently, the String class is preferable for a concatenation operation if a fixed number of String objects are concatenated. In that case, the individual concatenation operations might even be combined into a single operation by the compiler. A StringBuilder object is preferable for a concatenation operation if an arbitrary number of strings are concatenated; for example, if a loop concatenates a random number of strings of user input. </p>\n</blockquote>\n'}, {'answer_id': 6792, 'author': 'saalon', 'author_id': 111, 'author_profile': 'https://Stackoverflow.com/users/111', 'pm_score': 3, 'selected': False, 'text': "<p>I think in most cases like this clarity, and not efficiency, should be your biggest concern.  Unless you're crushing together tons of strings, or building something for a lower powered mobile device, this probably won't make much of a dent in your run speed.</p>\n\n<p>I've found that, in cases where I'm building strings in a fairly linear fashion, either doing straight concatenations or using StringBuilder is your best option.  I suggest this in cases where the majority of the string that you're building is dynamic.  Since very little of the text is static, the most important thing is that it's clear where each piece of dynamic text is being put in case it needs updated in the future.</p>\n\n<p>On the other hand, if you're talking about a big chunk of static text with two or three variables in it, even if it's a little less efficient, I think the clarity you gain from string.Format makes it worth it.  I used this earlier this week when having to place one bit of dynamic text in the center of a 4 page document.  It'll be easier to update that big chunk of text if its in one piece than having to update three pieces that you concatenate together.</p>\n"}, {'answer_id': 6824, 'author': 'Kev', 'author_id': 419, 'author_profile': 'https://Stackoverflow.com/users/419', 'pm_score': 8, 'selected': True, 'text': '<p><strong>NOTE:</strong> This answer was written when .NET 2.0 was the current version. This may no longer apply to later versions.</p>\n\n<p><code>String.Format</code> uses a <code>StringBuilder</code> internally:</p>\n\n<pre><code>public static string Format(IFormatProvider provider, string format, params object[] args)\n{\n    if ((format == null) || (args == null))\n    {\n        throw new ArgumentNullException((format == null) ? "format" : "args");\n    }\n\n    StringBuilder builder = new StringBuilder(format.Length + (args.Length * 8));\n    builder.AppendFormat(provider, format, args);\n    return builder.ToString();\n}\n</code></pre>\n\n<p>The above code is a snippet from mscorlib, so the question becomes "is <code>StringBuilder.Append()</code> faster than <code>StringBuilder.AppendFormat()</code>"? </p>\n\n<p>Without benchmarking I\'d probably say that the code sample above would run more quickly using <code>.Append()</code>. But it\'s a guess, try benchmarking and/or profiling the two to get a proper comparison.</p>\n\n<p>This chap, Jerry Dixon, did some benchmarking:</p>\n\n<blockquote>\n  <p><a href="http://jdixon.dotnetdevelopersjournal.com/string_concatenation_stringbuilder_and_stringformat.htm" rel="noreferrer">http://jdixon.dotnetdevelopersjournal.com/string_concatenation_stringbuilder_and_stringformat.htm</a></p>\n</blockquote>\n\n<p><strong>Updated:</strong></p>\n\n<p>Sadly the link above has since died. However there\'s still a copy on the Way Back Machine:</p>\n\n<blockquote>\n  <p><a href="http://web.archive.org/web/20090417100252/http://jdixon.dotnetdevelopersjournal.com/string_concatenation_stringbuilder_and_stringformat.htm" rel="noreferrer">http://web.archive.org/web/20090417100252/http://jdixon.dotnetdevelopersjournal.com/string_concatenation_stringbuilder_and_stringformat.htm</a></p>\n</blockquote>\n\n<p>At the end of the day it depends whether your string formatting is going to be called repetitively, i.e. you\'re doing some serious text processing over 100\'s of megabytes of text, or whether it\'s being called when a user clicks a button now and again. Unless you\'re doing some huge batch processing job I\'d stick with String.Format, it aids code readability. If you suspect a perf bottleneck then stick a profiler on your code and see where it really is.</p>\n'}, {'answer_id': 6838, 'author': 'GateKiller', 'author_id': 383, 'author_profile': 'https://Stackoverflow.com/users/383', 'pm_score': 0, 'selected': False, 'text': '<blockquote>\n  <p>In both cases above I want to inject one or more strings into the middle of a predefined template string.</p>\n</blockquote>\n\n<p>In which case, I would suggest String.Format is the quickest because it is design for that exact purpose.</p>\n'}, {'answer_id': 6849, 'author': 'McDowell', 'author_id': 304, 'author_profile': 'https://Stackoverflow.com/users/304', 'pm_score': 3, 'selected': False, 'text': '<p>I would expect <strong>String.Format</strong> to be slower - it has to parse the string and <em>then</em> concatenate it.</p>\n\n<p>Couple of notes:</p>\n\n<ul>\n<li><strong>Format</strong> is the way to go for user-visible strings in professional applications; this avoids localization bugs</li>\n<li>If you know the length of the resultant string beforehand, use the <strong>StringBuilder(Int32)</strong> constructor to predefine the capacity</li>\n</ul>\n'}, {'answer_id': 6884, 'author': 'Vaibhav', 'author_id': 380, 'author_profile': 'https://Stackoverflow.com/users/380', 'pm_score': 4, 'selected': False, 'text': "<p>I ran some quick performance benchmarks, and for 100,000 operations averaged over 10 runs, the first method (String Builder) takes almost half the time of the second (String Format).</p>\n\n<p>So, if this is infrequent, it doesn't matter. But if it is a common operation, then you may want to use the first method.</p>\n"}, {'answer_id': 6888, 'author': 'Vaibhav', 'author_id': 380, 'author_profile': 'https://Stackoverflow.com/users/380', 'pm_score': 2, 'selected': False, 'text': '<p>Oh also, the fastest would be:</p>\n\n<pre><code>string cat = "cat";\nstring s = "The " + cat + " in the hat";\n</code></pre>\n'}, {'answer_id': 902533, 'author': 'jrista', 'author_id': 111554, 'author_profile': 'https://Stackoverflow.com/users/111554', 'pm_score': 3, 'selected': False, 'text': '<p><code>String.Format</code> uses <code>StringBuilder</code> internally, so logically that leads to the idea that it would be a little less performant due to more overhead. However, a simple string concatenation is the fastest method of injecting one string between two others, by a significant degree. This evidence was demonstrated by Rico Mariani in his very first Performance Quiz, years ago. Simple fact is that concatenations, when the number of string parts is known (without limitation —\xa0you could concatenate a thousand parts, as long as you know it\'s always 1000 parts), are always faster than <code>StringBuilder</code> or <code>String.Format</code>. They can be performed with a single memory allocation and a series of memory copies. <a href="http://blogs.msdn.com/ricom/archive/2004/03/12/performance-quiz-1-of-a-series.aspx" rel="nofollow noreferrer">Here</a> is the proof.</p>\n<p>And here is the actual code for some <code>String.Concat</code> methods, which ultimately call <code>FillStringChecked</code>, which uses pointers to copy memory (extracted via Reflector):</p>\n<pre><code>public static string Concat(params string[] values)\n{\n    int totalLength = 0;\n\n    if (values == null)\n    {\n        throw new ArgumentNullException(&quot;values&quot;);\n    }\n\n    string[] strArray = new string[values.Length];\n\n    for (int i = 0; i &lt; values.Length; i++)\n    {\n        string str = values[i];\n        strArray[i] = (str == null) ? Empty : str;\n        totalLength += strArray[i].Length;\n\n        if (totalLength &lt; 0)\n        {\n            throw new OutOfMemoryException();\n        }\n    }\n\n    return ConcatArray(strArray, totalLength);\n}\n\npublic static string Concat(string str0, string str1, string str2, string str3)\n{\n    if (((str0 == null) &amp;&amp; (str1 == null)) &amp;&amp; ((str2 == null) &amp;&amp; (str3 == null)))\n    {\n        return Empty;\n    }\n\n    if (str0 == null)\n    {\n        str0 = Empty;\n    }\n\n    if (str1 == null)\n    {\n        str1 = Empty;\n    }\n\n    if (str2 == null)\n    {\n        str2 = Empty;\n    }\n\n    if (str3 == null)\n    {\n        str3 = Empty;\n    }\n\n    int length = ((str0.Length + str1.Length) + str2.Length) + str3.Length;\n    string dest = FastAllocateString(length);\n    FillStringChecked(dest, 0, str0);\n    FillStringChecked(dest, str0.Length, str1);\n    FillStringChecked(dest, str0.Length + str1.Length, str2);\n    FillStringChecked(dest, (str0.Length + str1.Length) + str2.Length, str3);\n    return dest;\n}\n\nprivate static string ConcatArray(string[] values, int totalLength)\n{\n    string dest = FastAllocateString(totalLength);\n    int destPos = 0;\n\n    for (int i = 0; i &lt; values.Length; i++)\n    {\n        FillStringChecked(dest, destPos, values[i]);\n        destPos += values[i].Length;\n    }\n\n    return dest;\n}\n\nprivate static unsafe void FillStringChecked(string dest, int destPos, string src)\n{\n    int length = src.Length;\n\n    if (length &gt; (dest.Length - destPos))\n    {\n        throw new IndexOutOfRangeException();\n    }\n\n    fixed (char* chRef = &amp;dest.m_firstChar)\n    {\n        fixed (char* chRef2 = &amp;src.m_firstChar)\n        {\n            wstrcpy(chRef + destPos, chRef2, length);\n        }\n    }\n}\n</code></pre>\n<p>So, then:</p>\n<pre><code>string what = &quot;cat&quot;;\nstring inthehat = &quot;The &quot; + what + &quot; in the hat!&quot;;\n</code></pre>\n<p>Enjoy!</p>\n'}, {'answer_id': 3383247, 'author': 'Liran', 'author_id': 2164233, 'author_profile': 'https://Stackoverflow.com/users/2164233', 'pm_score': 0, 'selected': False, 'text': '<p>It really depends on your usage pattern.<br>\nA detailed benchmark between <code>string.Join</code>, <code>string,Concat</code> and <code>string.Format</code> can be found here: <a href="http://www.liranchen.com/2010/07/stringformat-isnt-suitable-for.html" rel="nofollow noreferrer">String.Format Isn\'t Suitable for Intensive Logging</a></p>\n'}, {'answer_id': 27902469, 'author': 'Chris F Carroll', 'author_id': 550314, 'author_profile': 'https://Stackoverflow.com/users/550314', 'pm_score': 3, 'selected': False, 'text': '<p>If only because string.Format doesn\'t exactly do what you might think, here is a rerun of the tests 6 years later on Net45. </p>\n\n<p>Concat is still fastest but really it\'s less than 30% difference. StringBuilder and Format differ by barely 5-10%. I got variations of 20% running the tests a few times.</p>\n\n<p>Milliseconds, a million iterations:</p>\n\n<ul>\n<li>Concatenation: 367 </li>\n<li>New stringBuilder for each key: 452</li>\n<li>Cached StringBuilder: 419</li>\n<li>string.Format: 475</li>\n</ul>\n\n<p>The lesson I take away is that the performance difference is trivial and so it shouldn\'t stop you writing the simplest readable code you can. Which for my money is often but not always <code>a + b + c</code>.</p>\n\n<pre><code>const int iterations=1000000;\nvar keyprefix= this.GetType().FullName;\nvar maxkeylength=keyprefix + 1 + 1+ Math.Log10(iterations);\nConsole.WriteLine("KeyPrefix \\"{0}\\", Max Key Length {1}",keyprefix, maxkeylength);\n\nvar concatkeys= new string[iterations];\nvar stringbuilderkeys= new string[iterations];\nvar cachedsbkeys= new string[iterations];\nvar formatkeys= new string[iterations];\n\nvar stopwatch= new System.Diagnostics.Stopwatch();\nConsole.WriteLine("Concatenation:");\nstopwatch.Start();\n\nfor(int i=0; i&lt;iterations; i++){\n    var key1= keyprefix+":" + i.ToString();\n    concatkeys[i]=key1;\n}\n\nConsole.WriteLine(stopwatch.ElapsedMilliseconds);\n\nConsole.WriteLine("New stringBuilder for each key:");\nstopwatch.Restart();\n\nfor(int i=0; i&lt;iterations; i++){\n    var key2= new StringBuilder(keyprefix).Append(":").Append(i.ToString()).ToString();\n    stringbuilderkeys[i]= key2;\n}\n\nConsole.WriteLine(stopwatch.ElapsedMilliseconds);\n\nConsole.WriteLine("Cached StringBuilder:");\nvar cachedSB= new StringBuilder(maxkeylength);\nstopwatch.Restart();\n\nfor(int i=0; i&lt;iterations; i++){\n    var key2b= cachedSB.Clear().Append(keyprefix).Append(":").Append(i.ToString()).ToString();\n    cachedsbkeys[i]= key2b;\n}\n\nConsole.WriteLine(stopwatch.ElapsedMilliseconds);\n\nConsole.WriteLine("string.Format");\nstopwatch.Restart();\n\nfor(int i=0; i&lt;iterations; i++){\n    var key3= string.Format("{0}:{1}", keyprefix,i.ToString());\n    formatkeys[i]= key3;\n}\n\nConsole.WriteLine(stopwatch.ElapsedMilliseconds);\n\nvar referToTheComputedValuesSoCompilerCantOptimiseTheLoopsAway= concatkeys.Union(stringbuilderkeys).Union(cachedsbkeys).Union(formatkeys).LastOrDefault(x=&gt;x[1]==\'-\');\nConsole.WriteLine(referToTheComputedValuesSoCompilerCantOptimiseTheLoopsAway);\n</code></pre>\n'}]
['https://Stackoverflow.com/questions/6785', 'https://Stackoverflow.com', 'https://Stackoverflow.com/users/493/']