Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>I don't think so. Looking through Reflector, the implementation of <code>String.Join</code> looks very optimized. It also has the added benefit of knowing the total size of the string to be created in advance, so it doesn't need any reallocation.</p> <p>I have created two test methods to compare them:</p> <pre><code>public static string TestStringJoin(double[][] array) { return String.Join(Environment.NewLine, Array.ConvertAll(array, row =&gt; String.Join(",", Array.ConvertAll(row, x =&gt; x.ToString())))); } public static string TestStringBuilder(double[][] source) { // based on Marc Gravell's code StringBuilder sb = new StringBuilder(); foreach (var row in source) { if (row.Length &gt; 0) { sb.Append(row[0]); for (int i = 1; i &lt; row.Length; i++) { sb.Append(',').Append(row[i]); } } } return sb.ToString(); } </code></pre> <p>I ran each method 50 times, passing in an array of size <code>[2048][64]</code>. I did this for two arrays; one filled with zeros and another filled with random values. I got the following results on my machine (P4 3.0 GHz, single-core, no HT, running Release mode from CMD):</p> <pre><code>// with zeros: TestStringJoin took 00:00:02.2755280 TestStringBuilder took 00:00:02.3536041 // with random values: TestStringJoin took 00:00:05.6412147 TestStringBuilder took 00:00:05.8394650 </code></pre> <p>Increasing the size of the array to <code>[2048][512]</code>, while decreasing the number of iterations to 10 got me the following results:</p> <pre><code>// with zeros: TestStringJoin took 00:00:03.7146628 TestStringBuilder took 00:00:03.8886978 // with random values: TestStringJoin took 00:00:09.4991765 TestStringBuilder took 00:00:09.3033365 </code></pre> <p>The results are repeatable (almost; with small fluctuations caused by different random values). Apparently <code>String.Join</code> is a little faster most of the time (although by a very small margin).</p> <p>This is the code I used for testing:</p> <pre><code>const int Iterations = 50; const int Rows = 2048; const int Cols = 64; // 512 static void Main() { OptimizeForTesting(); // set process priority to RealTime // test 1: zeros double[][] array = new double[Rows][]; for (int i = 0; i &lt; array.Length; ++i) array[i] = new double[Cols]; CompareMethods(array); // test 2: random values Random random = new Random(); double[] template = new double[Cols]; for (int i = 0; i &lt; template.Length; ++i) template[i] = random.NextDouble(); for (int i = 0; i &lt; array.Length; ++i) array[i] = template; CompareMethods(array); } static void CompareMethods(double[][] array) { Stopwatch stopwatch = Stopwatch.StartNew(); for (int i = 0; i &lt; Iterations; ++i) TestStringJoin(array); stopwatch.Stop(); Console.WriteLine("TestStringJoin took " + stopwatch.Elapsed); stopwatch.Reset(); stopwatch.Start(); for (int i = 0; i &lt; Iterations; ++i) TestStringBuilder(array); stopwatch.Stop(); Console.WriteLine("TestStringBuilder took " + stopwatch.Elapsed); } static void OptimizeForTesting() { Thread.CurrentThread.Priority = ThreadPriority.Highest; Process currentProcess = Process.GetCurrentProcess(); currentProcess.PriorityClass = ProcessPriorityClass.RealTime; if (Environment.ProcessorCount &gt; 1) { // use last core only currentProcess.ProcessorAffinity = new IntPtr(1 &lt;&lt; (Environment.ProcessorCount - 1)); } } </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload