In another questions in SO (such as this one and this other one) it has been stated that the is
operator has worse performance compared to other options to check the type of an object.
I wanted to test this so I write some code (TIO link so you can run the tests and play with the code) and at first the results seemed to indicate that is
has indeed worse performance. Following are the relevant parts of the tests:
// is operator
var a = 0;
for (int i = 0; i < ITERATIONS; i++)
{
if (test is B) a += 1;
if (test is C) a += 2;
if (test is D) a += 3;
if (test is E) a += 4;
}
// typeof operator
var a = 0;
var t = test.GetType();
for (int i = 0; i < ITERATIONS; i++)
{
if (t == typeof(B)) a += 1;
if (t == typeof(C)) a += 2;
if (t == typeof(D)) a += 3;
if (t == typeof(E)) a += 4;
}
// TypeHandle
var a = 0;
var t = Type.GetTypeHandle(test);
for (int i = 0; i < ITERATIONS; i++)
{
if (t.Equals(typeof(B).TypeHandle)) a += 1;
if (t.Equals(typeof(C).TypeHandle)) a += 2;
if (t.Equals(typeof(D).TypeHandle)) a += 3;
if (t.Equals(typeof(E).TypeHandle)) a += 4;
}
When setting the number of iterations to 1000 and 10000 the results were as expected, but as I increased the number of iterations the results were inverted and now the is
performance was better. Following is the table you can get when playing with the number of iterations (times are in milliseconds):
ITERATIONS 1000 10000 100000 1000000 10000000
---------------------------------------------------------------
is 1.8608 2.1862 4.7757 28.1402 234.7027
typeof 0.4702 0.8296 3.9109 33.0174 328.5222
TypeHandle 0.5815 1.0586 6.1271 53.4649 536.3979
I get the same results (with different numbers, but the same result nonetheless) in my local machine: the higher the number of iterations, the faster is the performance of is
.
So what is happening here? Is this another consequence of branch prediction?