Note that there are some explanatory texts on larger screens.

plurals
  1. POWhy is using a Func<> so much faster than using the new() constraint on a generic sequence creator
    text
    copied!<p>Consider the following code...</p> <p>In my tests for a RELEASE (not debug!) x86 build on a Windows 7 x64 PC (Intel i7 3GHz) I obtained the following results:</p> <pre><code>CreateSequence() with new() took 00:00:00.9158071 CreateSequence() with creator() took 00:00:00.1383482 CreateSequence() with new() took 00:00:00.9198317 CreateSequence() with creator() took 00:00:00.1372920 CreateSequence() with new() took 00:00:00.9340462 CreateSequence() with creator() took 00:00:00.1447375 CreateSequence() with new() took 00:00:00.9344077 CreateSequence() with creator() took 00:00:00.1365162 </code></pre> <p>It seems that using a Func&lt;> to define a delegate to create new objects is more than 6 times faster than calling "new T()" directly. </p> <p>I find this slightly unexpected... I guess it's because of some inlining done by the Jitter, but I'd have thought that it would have been able to optimize the "new T()" just as well.</p> <p>Does anyone have an explanation for this?</p> <p>Maybe I'm making some mistake. (I've considered the effect the garbage collector might have, but rearranging the code and adding GC.Collect() and so on doesn't change the results significantly).</p> <p>Anyway, here's the code:</p> <pre><code>using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; namespace ConsoleApplication6 { class Program { static void Main(string[] args) { Stopwatch sw = new Stopwatch(); int repeats = 100; int count = 100000; for (int outer = 0; outer &lt; 4; ++outer) { sw.Restart(); for (int inner = 0; inner &lt; repeats; ++inner) { CreateSequence&lt;object&gt;(count).Count(); } Console.WriteLine("CreateSequence() with new() took " + sw.Elapsed); sw.Restart(); for (int inner = 0; inner &lt; repeats; ++inner) { CreateSequence(count, () =&gt; new object()).Count(); } Console.WriteLine("CreateSequence() with creator() took " + sw.Elapsed); Console.WriteLine(); } } public static IEnumerable&lt;T&gt; CreateSequence&lt;T&gt;(int n) where T: new() { for (int i = 0; i &lt; n; ++i) { yield return new T(); } } public static IEnumerable&lt;T&gt; CreateSequence&lt;T&gt;(int n, Func&lt;T&gt; creator) { for (int i = 0; i &lt; n; ++i) { yield return creator(); } } } } </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