<p>What's the most efficient way to concatenate strings?</p>

[{'answer_id': 21084, 'author': 'TheSmurf', 'author_id': 1975282, 'author_profile': 'https://Stackoverflow.com/users/1975282', 'pm_score': 2, 'selected': False, 'text': '<p>The most efficient is to use StringBuilder, like so:</p>\n\n<pre><code>StringBuilder sb = new StringBuilder();\nsb.Append("string1");\nsb.Append("string2");\n...etc...\nString strResult = sb.ToString();\n</code></pre>\n\n<p>@jonezy: String.Concat is fine if you have a couple of small things. But if you\'re concatenating megabytes of data, your program will likely tank.</p>\n'}, {'answer_id': 21093, 'author': 'TheEmirOfGroofunkistan', 'author_id': 1874, 'author_profile': 'https://Stackoverflow.com/users/1874', 'pm_score': 8, 'selected': True, 'text': '<p>The <code>StringBuilder.Append()</code> method is much better than using the <code>+</code> operator.  But I\'ve found that, when executing 1000 concatenations or less, <code>String.Join()</code> is even more efficient than <code>StringBuilder</code>.</p>\n\n<pre><code>StringBuilder sb = new StringBuilder();\nsb.Append(someString);\n</code></pre>\n\n<p>The only problem with <code>String.Join</code> is that you have to concatenate the strings with a common delimiter.</p>\n\n<p><strong>Edit:</strong> as <em>@ryanversaw</em> pointed out, you can make the delimiter <code>string.Empty</code>.</p>\n\n<pre><code>string key = String.Join("_", new String[] \n{ "Customers_Contacts", customerID, database, SessionID });\n</code></pre>\n'}, {'answer_id': 21097, 'author': 'Nick', 'author_id': 1490, 'author_profile': 'https://Stackoverflow.com/users/1490', 'pm_score': 1, 'selected': False, 'text': '<p>For just two strings, you definitely do not want to use StringBuilder.  There is some threshold above which the StringBuilder overhead is less than the overhead of allocating multiple strings.</p>\n\n<p>So, for more that 2-3 strings, use <a href="https://stackoverflow.com/questions/21078/whats-the-best-string-concatenation-method-using-c#21084">DannySmurf\'s code</a>.  Otherwise, just use the + operator.</p>\n'}, {'answer_id': 21113, 'author': 'palehorse', 'author_id': 312, 'author_profile': 'https://Stackoverflow.com/users/312', 'pm_score': 6, 'selected': False, 'text': '<p>From <a href="http://www.chinhdo.com/20070224/stringbuilder-is-not-always-faster/" rel="noreferrer">Chinh Do - StringBuilder is not always faster</a>:</p>\n\n<p><strong>Rules of Thumb</strong></p>\n\n<ul>\n<li><p>When concatenating <strong>three</strong> dynamic string values or less, use traditional string concatenation.</p></li>\n<li><p>When concatenating <strong>more than three</strong> dynamic string values, use <code>StringBuilder</code>.</p></li>\n<li><p>When building a big string from several string literals, use either the <code>@</code> string literal or the inline + operator.</p></li>\n</ul>\n\n<p><em>Most</em> of the time <code>StringBuilder</code> is your best bet, but there are cases as shown in that post that you should at least think about each situation.</p>\n'}, {'answer_id': 21114, 'author': 'Jon Dewees', 'author_id': 1365, 'author_profile': 'https://Stackoverflow.com/users/1365', 'pm_score': 0, 'selected': False, 'text': "<p>It would depend on the code. \nStringBuilder is more efficient generally, but if you're only concatenating a few strings and doing it all in one line, code optimizations will likely take care of it for you. It's important to think about how the code looks too: for larger sets StringBuilder will make it easier to read, for small ones StringBuilder will just add needless clutter.</p>\n"}, {'answer_id': 21118, 'author': 'Adam V', 'author_id': 517, 'author_profile': 'https://Stackoverflow.com/users/517', 'pm_score': 4, 'selected': False, 'text': '<p>If you\'re operating in a loop, <code>StringBuilder</code> is probably the way to go; it saves you the overhead of creating new strings regularly. In code that\'ll only run once, though, <code>String.Concat</code> is probably fine.</p>\n\n<p>However, Rico Mariani (.NET optimization guru) <a href="http://blogs.msdn.com/ricom/archive/2004/03/12/performance-quiz-1-of-a-series.aspx" rel="nofollow noreferrer">made up a quiz</a> in which he stated at the end that, in most cases, he recommends <code>String.Format</code>.</p>\n'}, {'answer_id': 21131, 'author': 'Lee', 'author_id': 1954, 'author_profile': 'https://Stackoverflow.com/users/1954', 'pm_score': 8, 'selected': False, 'text': '<p><a href="https://blogs.msdn.microsoft.com/ricom/" rel="noreferrer">Rico Mariani</a>, the .NET Performance guru, had <a href="https://blogs.msdn.microsoft.com/ricom/2003/12/15/more-stringbuilder-advice/" rel="noreferrer">an article</a> on this very subject.  It\'s not as simple as one might suspect.  The basic advice is this:</p>\n\n<blockquote>\n  <p>If your pattern looks like:</p>\n  \n  <p><code>x = f1(...) + f2(...) + f3(...) + f4(...)</code></p>\n  \n  <p>that\'s one concat and it\'s zippy, StringBuilder probably won\'t help.</p>\n  \n  <p>If your pattern looks like:  </p>\n  \n  <p><code>if (...) x += f1(...)</code><br>\n  <code>if (...) x += f2(...)</code><br>\n  <code>if (...) x += f3(...)</code><br>\n  <code>if (...) x += f4(...)</code>  </p>\n  \n  <p>then you probably want StringBuilder.</p>\n</blockquote>\n\n<p><a href="http://ericlippert.com/2013/06/17/string-concatenation-behind-the-scenes-part-one/" rel="noreferrer">Yet another article to support this claim</a> comes from Eric Lippert where he describes the optimizations performed on one line <code>+</code> concatenations in a detailed manner.</p>\n'}, {'answer_id': 164074, 'author': 'JohnIdol', 'author_id': 1311500, 'author_profile': 'https://Stackoverflow.com/users/1311500', 'pm_score': 3, 'selected': False, 'text': '<p>From this <a href="http://msdn.microsoft.com/en-us/library/ms973839.aspx" rel="nofollow noreferrer">MSDN article</a>:</p>\n\n<blockquote>\n  <p>There is some overhead associated with\n  creating a StringBuilder object, both\n  in time and memory. On a machine with\n  fast memory, a StringBuilder becomes\n  worthwhile if you\'re doing about five\n  operations. As a rule of thumb, I\n  would say 10 or more string operations\n  is a justification for the overhead on\n  any machine, even a slower one.</p>\n</blockquote>\n\n<p>So if you trust MSDN go with StringBuilder if you have to do more than 10 strings operations/concatenations - otherwise simple string concat with \'+\' is fine.</p>\n'}, {'answer_id': 6184000, 'author': 'Liran', 'author_id': 2164233, 'author_profile': 'https://Stackoverflow.com/users/2164233', 'pm_score': 1, 'selected': False, 'text': '<p>It really depends on your usage pattern.\nA detailed benchmark between string.Join, string,Concat and string.Format 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\n<p>(This is actually the same answer I gave to <a href="https://stackoverflow.com/questions/6785/is-string-format-as-efficient-as-stringbuilder">this</a> question)</p>\n'}, {'answer_id': 12257751, 'author': 'Mr_Green', 'author_id': 1577396, 'author_profile': 'https://Stackoverflow.com/users/1577396', 'pm_score': 7, 'selected': False, 'text': '<p>There are 6 types of string concatenations:</p>\n\n<ol>\n<li>Using the plus (<code>+</code>) symbol.</li>\n<li>Using <code>string.Concat()</code>.</li>\n<li>Using <code>string.Join()</code>.</li>\n<li>Using <code>string.Format()</code>.</li>\n<li>Using <code>string.Append()</code>.</li>\n<li>Using <code>StringBuilder</code>.</li>\n</ol>\n\n<p>In an experiment, it has been proved that <code>string.Concat()</code> is the best way to approach if the words are less than 1000(approximately) and if the words are more than 1000 then <code>StringBuilder</code> should be used.</p>\n\n<p>For more information, check this <a href="http://www.dotnetperls.com/string-concat" rel="noreferrer">site</a>. </p>\n\n<blockquote>\n  <h3>string.Join() vs string.Concat()</h3>\n  \n  <p>The string.Concat method here is equivalent to the string.Join method invocation with an empty separator. Appending an empty string is fast, but not doing so is even faster, so the <strong>string.Concat</strong> method would be superior here.</p>\n</blockquote>\n'}, {'answer_id': 19365619, 'author': 'talles', 'author_id': 1316620, 'author_profile': 'https://Stackoverflow.com/users/1316620', 'pm_score': 3, 'selected': False, 'text': '<p>It\'s also important to point it out that you should use the <code>+</code> operator if you are concatenating <a href="http://en.wikipedia.org/wiki/String_literal" rel="noreferrer">string literals</a>.</p>\n\n<blockquote>\n  <p>When you concatenate string literals or string constants by using the + operator, the compiler creates a single string. No run time concatenation occurs.</p>\n</blockquote>\n\n<p><a href="http://msdn.microsoft.com/library/ms228504.aspx" rel="noreferrer">How to: Concatenate Multiple Strings (C# Programming Guide)</a></p>\n'}, {'answer_id': 23266274, 'author': 'Dhibi_Mohanned', 'author_id': 3416010, 'author_profile': 'https://Stackoverflow.com/users/3416010', 'pm_score': 2, 'selected': False, 'text': '<p>System.String is immutable. When we modify the value of a string variable then a new memory is allocated to the new value and the previous memory allocation released. System.StringBuilder was designed to have concept of a mutable string where a variety of operations can be performed without allocation separate memory location for the modified string.</p>\n'}, {'answer_id': 26680343, 'author': 'DBN', 'author_id': 3192156, 'author_profile': 'https://Stackoverflow.com/users/3192156', 'pm_score': 3, 'selected': False, 'text': '<p>Adding to the other answers, please keep in mind that <a href="http://msdn.microsoft.com/en-us/library/h1h0a5sy.aspx" rel="nofollow noreferrer">StringBuilder can be told an initial amount of memory to allocate</a>.</p>\n<blockquote>\n<p>The <em>capacity</em> parameter defines the maximum number of characters that can be stored in the memory allocated by the current instance. Its value is assigned to the <a href="http://msdn.microsoft.com/en-us/library/system.text.stringbuilder.capacity.aspx" rel="nofollow noreferrer">Capacity</a> property. If the number of characters to be stored in the current instance exceeds this <em>capacity</em> value, the StringBuilder object allocates additional memory to store them.</p>\n<p>If <em>capacity</em> is zero, the implementation-specific default capacity is used.</p>\n</blockquote>\n<p>Repeatedly appending to a StringBuilder that hasn\'t been pre-allocated can result in a lot of unnecessary allocations just like repeatedly concatenating regular strings.</p>\n<p>If you know how long the final string will be, can trivially calculate it, or can make an educated guess about the common case (allocating too much isn\'t necessarily a bad thing), you should be providing this information to the constructor or the <a href="http://msdn.microsoft.com/en-us/library/system.text.stringbuilder.capacity.aspx" rel="nofollow noreferrer">Capacity</a> property. <em>Especially</em> when running performance tests to compare StringBuilder with other methods like String.Concat, which do the same thing internally. Any test you see online which doesn\'t include StringBuilder pre-allocation in its comparisons is wrong.</p>\n<p>If you can\'t make any kind of guess about the size, you\'re probably writing a utility function which should have its own optional argument for controlling pre-allocation.</p>\n'}, {'answer_id': 34558305, 'author': 'Eduardo Mass', 'author_id': 5696173, 'author_profile': 'https://Stackoverflow.com/users/5696173', 'pm_score': 3, 'selected': False, 'text': '<p>Try this 2 pieces of code and you will find the solution.</p>\n\n<pre><code> static void Main(string[] args)\n    {\n        StringBuilder s = new StringBuilder();\n        for (int i = 0; i &lt; 10000000; i++)\n        {\n            s.Append( i.ToString());\n        }\n        Console.Write("End");\n        Console.Read();\n    }\n</code></pre>\n\n<p>Vs</p>\n\n<pre><code>static void Main(string[] args)\n    {\n        string s = "";\n        for (int i = 0; i &lt; 10000000; i++)\n        {\n            s += i.ToString();\n        }\n        Console.Write("End");\n        Console.Read();\n    }\n</code></pre>\n\n<p>You will find that 1st code will end really quick and the memory will be in a good amount.</p>\n\n<p>The second code maybe the memory will be ok, but it will take longer... much longer.\nSo if you have an application for a lot of users and you need speed, use the 1st. If you have an app for a short term one user app, maybe you can use both or the 2nd will be more "natural" for developers.</p>\n\n<p>Cheers. </p>\n'}, {'answer_id': 43069670, 'author': 'RP Nainwal', 'author_id': 1106356, 'author_profile': 'https://Stackoverflow.com/users/1106356', 'pm_score': 3, 'selected': False, 'text': '<p>Following may be one more alternate solution to concatenate multiple strings.</p>\n\n<pre><code>String str1 = "sometext";\nstring str2 = "some other text";\n\nstring afterConcate = $"{str1}{str2}";\n</code></pre>\n\n<p><a href="https://stackoverflow.com/a/31014895/3546415">string interpolation</a></p>\n'}, {'answer_id': 47231853, 'author': 'Glenn Slayden', 'author_id': 147511, 'author_profile': 'https://Stackoverflow.com/users/147511', 'pm_score': 4, 'selected': False, 'text': '<p>Here is the fastest method I\'ve evolved over a decade for my large-scale NLP app. I have variations for <code>IEnumerable&lt;T&gt;</code> and other input types, with and without separators of different types (<code>Char</code>, <code>String</code>), but here I show the simple case of  <strong><em>concatenating all strings in an array</em></strong> into a single string, with no separator. Latest version here is developed and unit-tested on <strong>C# 7</strong> and <strong>.NET 4.7</strong>.</p>\n\n<p>There are two keys to higher performance; the first is to pre-compute the exact total size required. This step is trivial when the input is an array as shown here. For handling <code>IEnumerable&lt;T&gt;</code> instead, it is worth first gathering the strings into a temporary array for computing that total (The array is required to avoid calling <code>ToString()</code> more than once per element since technically, given the possibility of side-effects, doing so could change the expected semantics of a \'string join\' operation).</p>\n\n<p>Next, given the total allocation size of the final string, the biggest boost in performance is gained by <strong><em>building the result string in-place</em></strong>. Doing this requires the (perhaps controversial) technique of temporarily suspending the immutability of a new <code>String</code> which is initially allocated full of zeros. Any such controversy aside, however...</p>\n\n<blockquote>\n  <p>...note that this is the only bulk-concatenation solution on this page which entirely avoids an <em>extra round of allocation and copying</em> by the <code>String</code> constructor.</p>\n</blockquote>\n\n<p><strong>Complete code:</strong></p>\n\n<pre><code>/// &lt;summary&gt;\n/// Concatenate the strings in \'rg\', none of which may be null, into a single String.\n/// &lt;/summary&gt;\npublic static unsafe String StringJoin(this String[] rg)\n{\n    int i;\n    if (rg == null || (i = rg.Length) == 0)\n        return String.Empty;\n\n    if (i == 1)\n        return rg[0];\n\n    String s, t;\n    int cch = 0;\n    do\n        cch += rg[--i].Length;\n    while (i &gt; 0);\n    if (cch == 0)\n        return String.Empty;\n\n    i = rg.Length;\n    fixed (Char* _p = (s = new String(default(Char), cch)))\n    {\n        Char* pDst = _p + cch;\n        do\n            if ((t = rg[--i]).Length &gt; 0)\n                fixed (Char* pSrc = t)\n                    memcpy(pDst -= t.Length, pSrc, (UIntPtr)(t.Length &lt;&lt; 1));\n        while (pDst &gt; _p);\n    }\n    return s;\n}\n\n[DllImport("MSVCR120_CLR0400", CallingConvention = CallingConvention.Cdecl)]\nstatic extern unsafe void* memcpy(void* dest, void* src, UIntPtr cb);\n</code></pre>\n\n<p>I should mention that this code has a slight modification from what I use myself. In the original, I <a href="https://stackoverflow.com/a/47128947/147511">call the <strong>cpblk</strong> IL instruction</a> from <strong>C#</strong> to do the actual copying. For simplicity and portability in the code here, I replaced that with P/Invoke <code>memcpy</code> instead, as you can see. For highest performance on x64 (<a href="http://xoofx.com/blog/2010/10/23/high-performance-memcpy-gotchas-in-c/" rel="noreferrer">but maybe not x86</a>) you may want to use the <strong>cpblk</strong> method instead.</p>\n'}, {'answer_id': 48340975, 'author': 'asady', 'author_id': 9239715, 'author_profile': 'https://Stackoverflow.com/users/9239715', 'pm_score': 2, 'selected': False, 'text': '<p>Another solution:</p>\n\n<p>inside the loop, use List instead of string.</p>\n\n<pre><code>List&lt;string&gt; lst= new List&lt;string&gt;();\n\nfor(int i=0; i&lt;100000; i++){\n    ...........\n    lst.Add(...);\n}\nreturn String.Join("", lst.ToArray());;\n</code></pre>\n\n<p>it is very very fast.</p>\n'}, {'answer_id': 74502341, 'author': 'bertasoft', 'author_id': 3917318, 'author_profile': 'https://Stackoverflow.com/users/3917318', 'pm_score': 0, 'selected': False, 'text': '<p>I\'ve tested all the methods in this page and at the end I\'ve developed my solution that is the fastest and less memory expensive.</p>\n<p>Note: tested in Framework 4.8</p>\n<p><a href="https://i.stack.imgur.com/PqKti.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/PqKti.png" alt="enter image description here" /></a></p>\n<pre><code> [MemoryDiagnoser]\npublic class StringConcatSimple\n{\n    private string\n        title = &quot;Mr.&quot;, firstName = &quot;David&quot;, middleName = &quot;Patrick&quot;, lastName = &quot;Callan&quot;;\n\n    [Benchmark]\n    public string FastConcat()\n    {\n        return FastConcat(\n            title, &quot; &quot;, \n            firstName, &quot; &quot;,\n            middleName, &quot; &quot;, \n            lastName);\n    }\n\n    [Benchmark]\n    public string StringBuilder()\n    {\n        var stringBuilder =\n            new StringBuilder();\n\n        return stringBuilder\n            .Append(title).Append(\' \')\n            .Append(firstName).Append(\' \')\n            .Append(middleName).Append(\' \')\n            .Append(lastName).ToString();\n    }\n\n    [Benchmark]\n    public string StringBuilderExact24()\n    {\n        var stringBuilder =\n            new StringBuilder(24);\n\n        return stringBuilder\n            .Append(title).Append(\' \')\n            .Append(firstName).Append(\' \')\n            .Append(middleName).Append(\' \')\n            .Append(lastName).ToString();\n    }\n\n    [Benchmark]\n    public string StringBuilderEstimate100()\n    {\n        var stringBuilder =\n            new StringBuilder(100);\n\n        return stringBuilder\n            .Append(title).Append(\' \')\n            .Append(firstName).Append(\' \')\n            .Append(middleName).Append(\' \')\n            .Append(lastName).ToString();\n    }\n\n    [Benchmark]\n    public string StringPlus()\n    {\n        return title + \' \' + firstName + \' \' +\n            middleName + \' \' + lastName;\n    }\n\n    [Benchmark]\n    public string StringFormat()\n    {\n        return string.Format(&quot;{0} {1} {2} {3}&quot;,\n            title, firstName, middleName, lastName);\n    }\n\n    [Benchmark]\n    public string StringInterpolation()\n    {\n        return\n        $&quot;{title} {firstName} {middleName} {lastName}&quot;;\n    }\n\n    [Benchmark]\n    public string StringJoin()\n    {\n        return string.Join(&quot; &quot;, title, firstName,\n            middleName, lastName);\n    }\n\n    [Benchmark]\n    public string StringConcat()\n    {\n        return string.\n            Concat(new String[]\n            { title, &quot; &quot;, firstName, &quot; &quot;,\n                middleName, &quot; &quot;, lastName });\n    }\n}\n</code></pre>\n<p>Yes, it use unsafe</p>\n<pre><code>public static unsafe string FastConcat(string str1, string str2, string str3, string str4, string str5, string str6, string str7)\n    {\n        var capacity = 0;\n\n        var str1Length = 0;\n        var str2Length = 0;\n        var str3Length = 0;\n        var str4Length = 0;\n        var str5Length = 0;\n        var str6Length = 0;\n        var str7Length = 0;\n\n        if (str1 != null)\n        {\n            str1Length = str1.Length;\n            capacity = str1Length;\n        }\n\n        if (str2 != null)\n        {\n            str2Length = str2.Length;\n            capacity += str2Length;\n        }\n\n        if (str3 != null)\n        {\n            str3Length = str3.Length;\n            capacity += str3Length;\n        }\n\n        if (str4 != null)\n        {\n            str4Length = str4.Length;\n            capacity += str4Length;\n        }\n\n        if (str5 != null)\n        {\n            str5Length = str5.Length;\n            capacity += str5Length;\n        }\n\n        if (str6 != null)\n        {\n            str6Length = str6.Length;\n            capacity += str6Length;\n        }\n\n        if (str7 != null)\n        {\n            str7Length = str7.Length;\n            capacity += str7Length;\n        }\n\n\n        string result = new string(\' \', capacity);\n\n        fixed (char* dest = result)\n        {\n            var x = dest;\n\n            if (str1Length &gt; 0)\n            {\n                fixed (char* src = str1)\n                {\n                    Unsafe.CopyBlock(x, src, (uint)str1Length * 2); \n                    x += str1Length;\n                }\n            }\n\n            if (str2Length &gt; 0)\n            {\n                fixed (char* src = str2)\n                {\n                    Unsafe.CopyBlock(x, src, (uint)str2Length * 2);\n                    x += str2Length;\n                }\n            }\n\n            if (str3Length &gt; 0)\n            {\n                fixed (char* src = str3)\n                {\n                    Unsafe.CopyBlock(x, src, (uint)str3Length * 2);\n                    x += str3Length;\n                }\n            }\n\n            if (str4Length &gt; 0)\n            {\n                fixed (char* src = str4)\n                {\n                    Unsafe.CopyBlock(x, src, (uint)str4Length * 2);\n                    x += str4Length;\n                }\n            }\n\n            if (str5Length &gt; 0)\n            {\n                fixed (char* src = str5)\n                {\n                    Unsafe.CopyBlock(x, src, (uint)str5Length * 2);\n                    x += str5Length;\n                }\n            }\n\n            if (str6Length &gt; 0)\n            {\n                fixed (char* src = str6)\n                {\n                    Unsafe.CopyBlock(x, src, (uint)str6Length * 2);\n                    x += str6Length;\n                }\n            }\n\n            if (str7Length &gt; 0)\n            {\n                fixed (char* src = str7)\n                {\n                    Unsafe.CopyBlock(x, src, (uint)str7Length * 2);\n                }\n            }\n        }\n\n        return result;\n    }\n</code></pre>\n<p>You can edit the method and adapt it to your case. For example you can make it something like</p>\n<p>public static unsafe string FastConcat(string str1, string str2, string str3 = null, string str4 = null, string str5 = null, string str6 = null, string str7 = null)</p>\n'}]
['https://Stackoverflow.com/questions/21078', 'https://Stackoverflow.com', 'https://Stackoverflow.com/users/2358/']