Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 412
Steven Avatar asked Feb 07 '10 12:02

Steven


People also ask

What C is used for?

C programming language is a machine-independent programming language that is mainly used to create many types of applications and operating systems such as Windows, and other complicated programs such as the Oracle database, Git, Python interpreter, and games and is considered a programming foundation in the process of ...

What is the full name of C?

In the real sense it has no meaning or full form. It was developed by Dennis Ritchie and Ken Thompson at AT&T bell Lab. First, they used to call it as B language then later they made some improvement into it and renamed it as C and its superscript as C++ which was invented by Dr. Stroustroupe.

Is C language easy?

C is a general-purpose language that most programmers learn before moving on to more complex languages. From Unix and Windows to Tic Tac Toe and Photoshop, several of the most commonly used applications today have been built on C. It is easy to learn because: A simple syntax with only 32 keywords.

Is C or C++ same?

While C and C++ may sound similar, their features and usage differ. C is a procedural programming language that support objects and classes. On the other hand C++ is an enhanced version of C programming with object-oriented programming support.


2 Answers

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.

like image 166
Eric Lippert Avatar answered Sep 20 '22 02:09

Eric Lippert


This is a rough guess, but i think it's about the Array's relationship to its generic IEnumerable.

In the .NET Framework version 2.0, the Array class implements the System.Collections.Generic.IList, System.Collections.Generic.ICollection, and System.Collections.Generic.IEnumerable generic interfaces. The implementations are provided to arrays at run time, and therefore are not visible to the documentation build tools. As a result, the generic interfaces do not appear in the declaration syntax for the Array class, and there are no reference topics for interface members that are accessible only by casting an array to the generic interface type (explicit interface implementations). The key thing to be aware of when you cast an array to one of these interfaces is that members which add, insert, or remove elements throw NotSupportedException.

See MSDN Article.

It's not clear whether this relates to .NET 2.0+, but in this special case it would make perfect sense why the compiler cannot optimize your expression if it only becomes valid at run time.

like image 35
Marcel Jackwerth Avatar answered Sep 18 '22 02:09

Marcel Jackwerth