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?
