Search code examples
c#performanceoptimizationcil

C# compiler doesn’t optimize unnecessary casts


A few days back, while writing an answer for this question here on overflow I got a bit surprised by the C# compiler, who wasn’t doing what I expected it to do. Look at the following to code snippets:

First:

object[] array = new object[1];

for (int i = 0; i < 100000; i++)
{
    ICollection<object> col = (ICollection<object>)array;
    col.Contains(null);
}

Second:

object[] array = new object[1];

for (int i = 0; i < 100000; i++)
{
    ICollection<object> col = array;
    col.Contains(null);
}

The only difference in code between the two snippets is the cast to ICollection<object>. Because object[] implements the ICollection<object> interface explicitly, I expected the two snippets to compile down to the same IL and be, therefore, identical. However, when running performance tests on them, I noticed the latter to be about 6 times as fast as the former.

After comparing the IL from both snippets, I noticed the both methods were identical, except for a castclass IL instruction in the first snippet.

Surprised by this I now wonder why the C# compiler isn’t ‘smart’ here. Things are never as simple as it seems, so why is the C# compiler a bit naïve here?


Solution

  • My guess is that you have discovered a minor bug in the optimizer. There is all kinds of special-case code in there for arrays. Thanks for bringing it to my attention.