Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>The second will possibly be <em>almost certainly insignificantly</em> faster, because there's one fewer assignment involved, logically. In the first case, the code is actually equivalent to:</p> <pre><code>MyClass tmp = new MyClass() tmp.Id = 1; tmp.Code = "Test"; MyClass c = tmp; </code></pre> <p>It's very possible that the JIT compiler will elide these as you're declaring a <em>new</em> variable - it wouldn't be able to do so if you were assigning to an existing variable with an object initializer.</p> <p>EDIT: I've just tried compiling with and without optimizations turned on, and in this "new variable" case the C# compiler elides the two <em>if</em> it's optimizing. It doesn't otherwise (but the JIT still could). In the "reassignment" case it could make an observable difference, so I wouldn't expect the same optimization. I haven't checked though.</p> <p>I would be very surprised to see a situation where it actually made a significant difference though, so I'd go with the more readable option, which IMO is the first.</p> <p>EDIT: I thought folks might be interested in a benchmark showing it making a difference. This is deliberately horrible code to make the hidden extra assignment slow - I've created a big, mutable struct. Urgh. Anyway...</p> <pre><code>using System; using System.Diagnostics; struct BigStruct { public int value; #pragma warning disable 0169 decimal a1, a2, a3, a4, a5, a6, a7, a8; decimal b1, b2, b3, b4, b5, b6, b7, b8; decimal c1, c2, c3, c4, c5, c6, c7, c8; decimal d1, d2, d3, d4, d5, d6, d7, d8; #pragma warning restore 0169 } class Test { const int Iterations = 10000000; static void Main() { Time(NewVariableObjectInitializer); Time(ExistingVariableObjectInitializer); Time(NewVariableDirectSetting); Time(ExistingVariableDirectSetting); } static void Time(Func&lt;int&gt; action) { Stopwatch stopwatch = Stopwatch.StartNew(); action(); stopwatch.Stop(); Console.WriteLine("{0}: {1}ms", action.Method.Name, stopwatch.ElapsedMilliseconds); } static int NewVariableObjectInitializer() { int total = 0; for (int i = 0; i &lt; Iterations; i++) { BigStruct b = new BigStruct { value = i }; total += b.value; } return total; } static int ExistingVariableObjectInitializer() { int total = 0; BigStruct b; for (int i = 0; i &lt; Iterations; i++) { b = new BigStruct { value = i }; total += b.value; } return total; } static int NewVariableDirectSetting() { int total = 0; for (int i = 0; i &lt; Iterations; i++) { BigStruct b = new BigStruct(); b.value = i; total += b.value; } return total; } static int ExistingVariableDirectSetting() { int total = 0; BigStruct b; for (int i = 0; i &lt; Iterations; i++) { b = new BigStruct(); b.value = i; total += b.value; } return total; } } </code></pre> <p>Results (with /o+ /debug-):</p> <pre><code>NewVariableObjectInitializer: 3328ms ExistingVariableObjectInitializer: 3300ms NewVariableDirectSetting: 1464ms ExistingVariableDirectSetting: 1491ms </code></pre> <p>I'm somewhat surprised that the NewVariableObjectInitializer version is slower than the direct setting ones... it looks like the C# compiler doesn't optimize this case in the way that it does for reference types. I suspect there's some subtlety around value types that prevents it.</p>
 

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