Ich möchte, dass wissen, welche Aussage von einem Performance-Sicht nützlich ist obWas ist gut zu verwenden: Object.GetType() == typeof (Typ) oder Objekt ist Typ?
Object.GetType() == typeof(Type)
oder
Object is Type
Ich möchte, dass wissen, welche Aussage von einem Performance-Sicht nützlich ist obWas ist gut zu verwenden: Object.GetType() == typeof (Typ) oder Objekt ist Typ?
Object.GetType() == typeof(Type)
oder
Object is Type
die zweite verwenden:
Object is Type
Getestet diese 1'000'000'000 mal mit string
gegen int
man bekommt:
//Release
00:00:18.1428040 //Object.GetType() == typeof(Type)
00:00:03.9791070 //Object is Type
//Debug
00:00:21.3545510 //Object.GetType() == typeof(Type)
00:00:06.2969510 //Object is Type
//Machine specs:
//Intel(R) Core(TM) i5-3210M CPU @ 2.50GHz
//6 GB RAM memory
//Ubuntu 14.04 (OS)
//Runtime: Mono JIT compiler version 3.2.8
//Compiler: Mono dmcs
//Notes: ran these with some background processes, but the difference in time
// is significant enough I guess.
Hinweis: Es gibt einen starken semantischen Unterschied zwischen den beide:
- Die Gleichheit
==
Kontrollen Art Gleichheit: mit anderen Worten, wennA : B
als der Gleichheitstest wird fürA.GetType() == typeof(B)
fehlschlagen, währendA is B
wird erfolgreich sein.- Wenn das Objekt
null
ist, wird es eineSystem.NullReferenceException
werfen. Im zweiten Fall wirdfalse
zurückgegeben.
Dies ist eher Logik von einem Compiler Point-of-View: in der ersten Variante Sie das Objekt für seinen Typen abfragen. Falls das nicht wirklich optimiert ist, führen Sie zuerst einen Funktionsaufruf durch, dieser Aufruf sagt dann, dass er einen Zeiger auf die Typentabelle zurückgeben muss.
Im zweiten Fall verzichten Sie auf solche Aufrufe: Der Compiler wird sie spezialisieren, indem er den Typcode zurückgibt. Und wenn die Type
im Voraus bekannt ist, kann es sogar einen sehr schnellen Test dafür erarbeiten.
Beachten Sie weiterhin, dass für einige triviale Fälle Object is Type
optimiert werden kann: zum Beispiel, weil der Compiler bereits ableiten kann, dass Object
nicht immer vom Typ Type
sein kann.
Fortgeschrittenere
Man kann auch die CIL virtuelle Maschine Quellcode analysiert, für die erste Variante, ist dies:
IL_0000: ldarg.0
IL_0001: callvirt instance class [mscorlib]System.Type [mscorlib]System.Object::GetType()
IL_0006: ldtoken [mscorlib]System.Int32
IL_000b: call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle)
IL_0010: call bool [mscorlib]System.Type::op_Equality(class [mscorlib]System.Type, class [mscorlib]System.Type)
IL_0015: ret
Für die zweite Variante ist das:
IL_0000: ldarg.0
IL_0001: isinst [mscorlib]System.Int32
IL_0006: ldnull
IL_0007: cgt.un
IL_0009: ret
(Sie können natürlich andere Typen ausfüllen). Jetzt sind die ldarg.0
und ret
einfach Nebenprodukte der Verwendung einer Methode, so dass man sie ignorieren kann.
Was man sieht, ist, dass man in der ersten Variante die GetType
-Methode explizit aufruft und dann den ==
-Operator aufruft. Funktionsaufrufe sind im Allgemeinen teuer. In der zweiten Variante wird sofort nach isinst
gesucht. Der Code benötigt weniger Bytes und verwendet weniger teure Methoden.Obwohl die Leistung natürlich von der Implementierung der Laufzeitumgebung abhängt, denke ich, dass es ziemlich sicher ist zu sagen, dass die zweite Variante fast immer die erste hinsichtlich der Leistung schlagen wird.
Ein Compiler könnte wahrscheinlich spezialisieren die erste Variante, so dass es so effizient wie die zweite läuft, aber der Mono C# -Compiler scheint dies nicht zu tun. Wahrscheinlich keiner der verfügbaren C# -Compiler wird.
Ich kann diese Antwort nicht innerhalb von 4 Minuten akzeptieren? –
@AmolBavannavar: das gibt anderen Benutzern die Möglichkeit, eine bessere Antwort zu finden. Und für eine solche Frage ist das sehr wahrscheinlich. –
aber die Art, wie Sie diese Frage beantwortet haben, ist sehr gut. Es ist das was ich von diesem Thread will. Ich habs . Vielen Dank .. –
http://StackOverflow.com/Questions/983030/Type-Checking-Typeof-Gettype-or-? Rq = 1 – Bharadwaj
Es ist wichtig zu verstehen, diese beiden sind nicht gleichwertig und wenn es um Vererbung oder Schnittstellen geht, wird man Rückkehr falsch und die andere wahr. Bharadwajs verbundene Frage zeigt diese Unterschiede. – AaronLS
Sie können dies selbst getestet haben. – t3chb0t