Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# 'is' operator performance

I have a program that requires fast performance. Within one of its inner loops, I need to test the type of an object to see whether it inherits from a certain interface.

One way to do this would be with the CLR's built-in type-checking functionality. The most elegant method there probably being the 'is' keyword:

if (obj is ISpecialType) 

Another approach would be to give the base class my own virtual GetType() function which returns a pre-defined enum value (in my case, actually, i only need a bool). That method would be fast, but less elegant.

I have heard that there is an IL instruction specifically for the 'is' keyword, but that doesn't mean it executes fast when translated into native assembly. Can anyone share some insight into the performance of 'is' versus the other method?

UPDATE: Thanks for all the informed answers! It seem a couple helpful points are spread out among the answers: Andrew's point about 'is' automatically performing a cast is essential, but the performance data gathered by Binary Worrier and Ian is also extremely useful. It would be great if one of the answers were edited to include all of this information.

like image 789
JubJub Avatar asked Mar 26 '09 16:03

JubJub


People also ask

Bahasa C digunakan untuk apa?

Meskipun C dibuat untuk memprogram sistem dan jaringan komputer namun bahasa ini juga sering digunakan dalam mengembangkan software aplikasi. C juga banyak dipakai oleh berbagai jenis platform sistem operasi dan arsitektur komputer, bahkan terdapat beberepa compiler yang sangat populer telah tersedia.

C dalam Latin berapa?

C adalah huruf ketiga dalam alfabet Latin. Dalam bahasa Indonesia, huruf ini disebut ce (dibaca [tʃe]).

Bahasa C dibuat pertama kali oleh siapa dan tahun berapa?

Bahasa pemrograman C ini dikembangkan antara tahun 1969 – 1972 oleh Dennis Ritchie. Yang kemudian dipakai untuk menulis ulang sistem operasi UNIX. Selain untuk mengembangkan UNIX, bahasa C juga dirilis sebagai bahasa pemrograman umum.


2 Answers

Using is can hurt performance if, once you check the type, you cast to that type. is actually casts the object to the type you are checking so any subsequent casting is redundant.

If you are going to cast anyway, here is a better approach:

ISpecialType t = obj as ISpecialType;  if (t != null) {     // use t here } 
like image 179
Andrew Hare Avatar answered Sep 21 '22 10:09

Andrew Hare


I'm with Ian, you probably don't want to do this.

However, just so you know, there is very little difference between the two, over 10,000,000 iterations

  • The enum check comes in at 700 milliseconds (approx)
  • The IS check comes in at 1000 milliseconds (approx)

I personally wouldn't fix this problem this way, but if I was forced to pick one method it would be the built in IS check, the performance difference isn't worth considering the coding overhead.

My base and derived classes

class MyBaseClass {     public enum ClassTypeEnum { A, B }     public ClassTypeEnum ClassType { get; protected set; } }  class MyClassA : MyBaseClass {     public MyClassA()     {         ClassType = MyBaseClass.ClassTypeEnum.A;     } } class MyClassB : MyBaseClass {     public MyClassB()     {         ClassType = MyBaseClass.ClassTypeEnum.B;     } } 

JubJub: As requested more info on the tests.

I ran both tests from a console app (a debug build) each test looks like the following

static void IsTest() {     DateTime start = DateTime.Now;     for (int i = 0; i < 10000000; i++)     {         MyBaseClass a;         if (i % 2 == 0)             a = new MyClassA();         else             a = new MyClassB();         bool b = a is MyClassB;     }     DateTime end = DateTime.Now;     Console.WriteLine("Is test {0} miliseconds", (end - start).TotalMilliseconds); } 

Running in release, I get a difference of 60 - 70 ms, like Ian.

Further Update - Oct 25th 2012
After a couple of years away I noticed something about this, the compiler can choose to omit bool b = a is MyClassB in release because b isn't used anywhere.

This code . . .

public static void IsTest() {     long total = 0;     var a = new MyClassA();     var b = new MyClassB();     var sw = new Stopwatch();     sw.Start();     for (int i = 0; i < 10000000; i++)     {         MyBaseClass baseRef;         if (i % 2 == 0)             baseRef = a;//new MyClassA();         else             baseRef = b;// new MyClassB();         //bool bo = baseRef is MyClassB;         bool bo = baseRef.ClassType == MyBaseClass.ClassTypeEnum.B;         if (bo) total += 1;     }     sw.Stop();     Console.WriteLine("Is test {0} miliseconds {1}", sw.ElapsedMilliseconds, total); } 

. . . consistently shows the is check coming in at approx 57 milliseconds, and the enum comparison coming in at 29 milliseconds.

NB I'd still prefer the is check, the difference is too small to care about

like image 35
Binary Worrier Avatar answered Sep 21 '22 10:09

Binary Worrier