2013-05-24 7 views
13

Gesetzt Ich habe eine Klasse MyType:Was ist effizienter: myType.GetType() oder typeof (MyType)?

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

der folgende Code Gegeben:

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

Welche dieser Variablenzuweisungen wäre die effizienteste sein?

Ist die Leistung von GetType() oder typeof() genug, dass es vorteilhaft wäre, den Typ in einem statischen Feld zu speichern?

+0

Erhalten Sie die Instanz zur Laufzeit (dynamisch, Generika?) Oder ist es bei compiletime angegeben? –

+0

@newStackExchangeInstance Ich frage einfach im Zusammenhang mit dem genauen Code, den ich zur Verfügung gestellt habe. – Dan

Antwort

20

typeof(SomeType) ist eine einfache Metadatentoken Lookup

GetType() ein virtuelles Call ist; Auf der Plusseite erhalten Sie den abgeleiteten Typ, wenn es eine Unterklasse ist, aber auf der Minusseite erhalten Sie die abgeleitete Klasse, wenn es eine Unterklasse ist. Wenn du verstehst was ich meine. Darüber hinaus erfordert GetType() Boxen für Strukturen und funktioniert nicht gut für nullable Strukturen. Wenn Sie den Typ bei compiletime kennen, verwenden Sie typeof().

+0

Wie benötigt 'GetType' Boxen für Strukturen? – Dan

+0

@Dan, weil es sich um einen virtuellen Anruf handelt, der nicht überschrieben werden kann. Alle anderen Struct-Methoden (Equals, ToString, GetHashCode usw.) können überschrieben werden, sodass sie ohne Boxing entweder über Call oder Constrained-Call aufgerufen werden können. Um jedoch eine nicht überschriebene Methode für eine Struktur aufzurufen, müssen Sie die virtuelle Methode für das Objekt boxen und dann aufrufen. –

+0

Bekam es. Daran habe ich nie gedacht. Vielen Dank! – Dan

5

Ich würde mit Typ2 gehen. Es muss keine Instanz zum Abrufen des Typs instanziiert werden. Und es ist am menschlichsten lesbar.

+0

Das sind gute Punkte, aber mir geht es mehr um Effizienz als um Lesbarkeit. – Dan

-1

Beide im Grunde gleich. Obwohl typeof kann wie

typeof(MyClass); 

Aber

MyClass.GetType(); 

nicht einmal bauen, da Sie eine Instanz der Klasse haben, müssen auf einer nicht-Instanz der Klasse verwendet werden.

Lange Rede kurzer Sinn, beide machen die gleiche Arbeit in einem anderen Kontext.

+0

Ich verstehe, dass alle 3 der Variablenzuordnungen, die ich zur Verfügung gestellt habe, funktional gleichwertig sind, aber ich frage mich, welches effizienter ist. – Dan

+0

Technisch wird Typeof schneller sein. – ncourcy84

+0

Ich spreche nur technisch. Ich weiß nicht wie. Was lässt Sie sagen, dass es effizienter ist? – Dan

4

Der einzige Weg, um herauszufinden, ist zu messen.

Die Variante "Typ1" ist nicht zuverlässig oder wird in keiner Weise empfohlen, da nicht alle Typen konstruiert werden können. Schlimmer noch, es reserviert Speicher, der Garbage Collector sein muss und ruft die Objektkonstruktoren auf.

Für die verbleibenden zwei Optionen ist "type3" auf meinem Rechner etwa doppelt so schnell wie "type1" sowohl im Debug- als auch im Release-Modus. Denken Sie daran, dass dies nur für meinen Test gilt - die Ergebnisse sind möglicherweise für andere Prozessortypen, Maschinentypen, Compiler oder .NET-Versionen nicht zutreffend.

 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); 

Das sagte, es ist ein bisschen alarmierend diese Frage wird ohne eine klare Anforderung gestellt. Wenn Sie ein Leistungsproblem festgestellt haben, haben Sie wahrscheinlich bereits ein Profil erstellt und wissen, welche Option besser ist. Das sagt mir, dass dies wahrscheinlich vorzeitige Optimierung ist - Sie kennen das Sprichwort, "vorzeitige Optimierung ist die Wurzel allen Übels".

Programmiercode wird nicht nur nach Leistung gemessen. Es wird auch durch Korrektheit, Entwicklerproduktivität und Wartbarkeit gemessen. Erhöhen Sie die Komplexität Ihres Codes ohne eine starke Grund nur überträgt diese Kosten auf woanders. Was ein Nicht-Problem sein könnte, hat sich jetzt und in Zukunft zu einem ernsthaften Produktivitätsverlust für die zukünftigen Betreuer der Anwendung entwickelt.

Meine Empfehlung wäre, immer die "type1" Variante zu verwenden. Der von mir aufgeführte Messcode ist kein realistisches Szenario. Das Caching von typeof zu einer Referenzvariable hat wahrscheinlich eine Menge Nebenwirkungen, insbesondere in der Art, wie .NET Assemblys lädt. Anstatt sie nur bei Bedarf laden zu lassen, kann es am Ende bei jeder Verwendung der Anwendung zu einer einzigen geladen werden - was eine theoretische Leistungsoptimierung zu einem sehr realen Leistungsproblem macht.

+0

Entschuldigung, wenn die Antwort ein wenig predigerisch war, ich stelle mir nur vor, dass Google dies aufhebt und Tausende von Anfänger-Entwicklern plötzlich den typeof() -Operator wegwerfen! – ShadowChaser

2

Sie sind ziemlich anders.

typeof(MyType) bekommt ein Type Objekt beschreibt die MyType aufgelöst Typ in der Kompilierung-Typ die ldtoken Anweisung verwendet wird.

myInstance.GetType() Ruft das Objekt Type auf, das den Laufzeittyp der Variablen myInstance beschreibt.

Beide sind für verschiedene Szenarien gedacht.

Sie können typeof(MyType) nicht verwenden, es sei denn, Sie kennen den Typ zur Kompilierzeit und haben Zugriff darauf.

Sie können myInstance.GetType() nicht verwenden, es sei denn, Sie haben eine Instanz dieses Typs.

typeof(MyType) ist immer effizienter, aber Sie können nicht verwenden, wenn Sie den Typ zum Zeitpunkt der Kompilierung nicht sehen. Sie können typeof(MyType) nicht verwenden, um den tatsächlichen Laufzeittyp einer Variablen zu lernen, da Sie den Typ nicht kennen.

+0

Ich verstehe ihre Unterschiede in Bezug auf die Verwendung. Für das Beispiel, das ich gepostet habe, sind die Ergebnisse Objekte des gleichen Typs. Meine Frage ist, welche ist effizienter und warum? – Dan

Verwandte Themen