В других вопросах в SO (таких как этот и этот другой ) было указано, что оператор is
имеет более низкую производительность по сравнению с другими вариантами проверкитип объекта.
Я хотел проверить это, поэтому я пишу некоторый код ( TIO link , чтобы вы могли запускать тесты и играть с кодом), и сначала результаты, казалось, указываличто is
действительно хуже производительности.Ниже приведены соответствующие части тестов:
// 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;
}
При установке числа итераций равным 1000 и 10000 результаты были ожидаемыми, но по мере увеличения количества итераций результаты были инвертированы, и теперь is
производительность была лучше.Ниже приведена таблица, которую вы можете получить, играя с количеством итераций (время указывается в миллисекундах):
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
Я получаю одинаковые результаты (с разными числами, но, тем не менее, с тем же результатом) на моей локальной машине: чем больше число итераций, тем выше производительность is
.
Так что же здесь происходит?Является ли это еще одним следствием предсказания ветвления ?