2013-05-24 4 views
13

Предположив У меня есть класс MyType:Что более эффективно: myType.GetType() или typeof (MyType)?

sealed class MyType 
{ 
    static Type typeReference = typeof(MyType); 
    //... 
} 

Учитывая следующий код:

var instance = new MyType(); 
var type1 = instance.GetType(); 
var type2 = typeof(MyType); 
var type3 = typeReference; 

Какой из этих назначений переменных будет наиболее эффективным?

Является ли производительность GetType() или typeof() относительно достаточной, чтобы было полезно сохранить тип в статическом поле?

+0

Вы получаете экземпляр во время выполнения (динамический, generics?) Или он указан в compiletime? –

+0

@newStackExchangeInstance Я просто спрашиваю в контексте точного кода, который я предоставил. – Dan

ответ

20

typeof(SomeType) является простыми метаданными маркера поиска

GetType() представляет собой виртуальный вызов; на стороне плюса вы получите производный тип, если он является подклассом, но на минусовой стороне вы получите производный класс, если он является подклассом. Если вы понимаете, что я имею в виду. Кроме того, GetType() требует бокса для структур и не подходит для нулевых структур.

Если вы знаете тип в compiletime, используйте typeof().

+0

Как «GetType» требует бокса для структур? – Dan

+0

@ Да, потому что это виртуальный вызов, который нельзя переопределить. Все остальные методы структуры (Equals, ToString, GetHashCode и т. Д.) Могут быть переопределены, что позволяет их вызывать без бокса через вызов или принудительный вызов. Но для вызова непереопределенного метода для структуры требуется бокс, а затем вызов виртуального метода на объект. –

+0

Получил. Я никогда об этом не думал. Благодаря! – Dan

5

Я бы пошел с type2. Это не требует создания экземпляра экземпляра для получения типа. И это самый читаемый человек.

+0

Это хорошие моменты, но я забочусь об эффективности больше, чем о читаемости. – Dan

-1

Оба в основном то же самое. Хотя TypeOf может быть применен на класс, не например, как

typeof(MyClass); 

Но

MyClass.GetType(); 

даже не строить, так как вы должны иметь экземпляр класса.

Короче говоря, они оба выполняют ту же работу в другом контексте.

+0

Я понимаю, что все три присваивания переменных, которые я предоставил, функционально эквивалентны, но мне интересно, что более эффективно. – Dan

+0

Технически говоря тип будет быстрее. – ncourcy84

+0

Я только говорю технически. Я не знаю, как этого не делать. Что заставляет вас сказать, что он более эффективен? – Dan

4

Единственный способ узнать - измерить.

Вариант «type1» не является надежным или рекомендовал каким-либо образом, поскольку не все типы могут быть сконструированы. Хуже того, он выделяет память, которая должна быть сборщиком мусора и вызывает конструкторы объектов.

Для оставшихся двух вариантов на моей машине «type3» примерно в два раза быстрее, чем «type1» в обоих режимах отладки и выпуска. Помните, что это справедливо только для моего теста - результаты могут быть неверными для других типов процессоров, типов машин, компиляторов или версий .NET.

 var sw = System.Diagnostics.Stopwatch.StartNew(); 
     for (int i = 0; i < 10000000; i++) 
     { 
      var y = typeof(Program).ToString(); 
     } 
     sw.Stop(); 
     Console.WriteLine(sw.ElapsedMilliseconds); 

     sw.Restart(); 
     for (int i = 0; i < 10000000; i++) 
     { 
      var y = typeReference.ToString(); 
     } 
     sw.Stop(); 
     Console.WriteLine(sw.ElapsedMilliseconds); 

Сказали, что это немного тревожно, этот вопрос задается без четкого требования. Если вы заметили проблему с производительностью, вы, вероятно, уже профилировали ее и знали, какой вариант лучше. Это говорит мне о том, что это, вероятно, преждевременная оптимизация - вы знаете высказывание: «преждевременная оптимизация - это корень всего зла».

Код программы не измеряется только производительностью. Он также измеряется правильностью, производительностью разработчика и ремонтопригодностью. Повышая сложность вашего кода без , прочный аргумент просто переносит стоимость в другое место. То, что могло быть проблемой без проблем, теперь превратилось в серьезную потерю производительности, как сейчас, так и будущих сторонников приложения.

Моя рекомендация заключалась в том, чтобы всегда использовать вариант «type1». Перечисленный мной код измерения не является реальным сценарием. Кэширование typeof для ссылочной переменной, вероятно, имеет массу побочных эффектов, особенно вокруг того, как .NET загружает сборки. Вместо того, чтобы загружать их только по мере необходимости, это может привести к загрузке каждого из них при каждом использовании приложения - превращение теоретической оптимизации производительности в очень реальную проблему с производительностью.

+0

Извинения, если ответ был немного преданным, я просто представляю, как Google собирает это, и тысячи начинающих разработчиков внезапно выбрасывают оператор typeof()! – ShadowChaser

2

Они довольно разные.

typeof(MyType) получает Type объекта, описывающий тип MyType разрешенного в компиляции типа с использованием ldtoken инструкции.

myInstance.GetType() получает объект Type, описывающий тип времени выполнения переменной myInstance.

Оба предназначены для разных сценариев.

Вы не можете использовать typeof(MyType), если не знаете тип во время компиляции и имеете к нему доступ.

Вы не можете использовать myInstance.GetType(), если у вас нет экземпляра такого типа.

typeof(MyType) всегда более эффективен, но вы не можете использовать, если вы не видите тип во время компиляции. Вы не можете использовать typeof(MyType), чтобы узнать реальный тип выполнения некоторой переменной, потому что вы не знаете тип.

+0

Я понимаю их различия в отношении использования. В примере, который я опубликовал, результаты будут такими же типами объектов. Мой вопрос в том, что является более эффективным и почему? – Dan