Was ist das mit Downcasting Hit Leistung?
Frage
Ich versuche nur, meinen Kopf um Generics zu erhalten, indem dieses erhellende Artikel von Juval Lowy
Paraphrasieren .. Wenn Sie eine generische Klassendefinition definieren, wird es in IL kompiliert.
- Für Value-Typen, sobald Sie einen bestimmten Wert Typen anfordern, ersetzt es die T mit Ihrem spezifischen Werttyp des IL für diese spezielle Konfiguration zu erhalten z.B.
MyList<int>
Vorteil:. Keine Boxen und Unboxing Strafen - Alle gut .. für Referenztypen ersetzt der Compiler alle Instanzen von T in Ihrer Definition mit Objekt und erstellt die IL, die für alle Arten ref verwendet wird. Instanzen jedoch zugeordnet sind, auf der Grundlage des tatsächlichen angeforderten ref Typ z.B.
MyList<String>
Jetzt vorab Generika wir Methoden geschrieben haben könnte, die Object
Parameter übernehmen. Generics behauptet, 100% Leistungsverbesserung, da ' es die Leistungseinbuße vermeidet Sie entstehen, wenn Sie den Objekttyp auf Ihre speziellen Typ niedergeschlagenen, wenn Sie es verwenden möchten
// assume GetItem returns an Object
string sMyPreciousString = (string) obList.GetItem();
Was ist das Leistungseinbußen, wenn Sie gesenkten von Objekt zu spezifischen Referenztyp? es scheint auch, wie oben Guss auf Object (Generics auch dies tun würde), ist kein Leistungseinbruch .. warum?
Lösung
Upcasting zum Objekt keine Ausführungszeit Check erfordern -. Es wird immer funktionieren, und ist nur eine no-op im Grunde
einziehe erfordert eine Ausführungszeit überprüfen, um sicherzustellen Sie keinen Strom in einen String zum Beispiel Gießen. Es ist eine ziemlich kleine Strafe und sehr unwahrscheinlich, dass ein Engpass zu sein -. Aber es ist nur ein zusätzlicher Vorteil für Generika zu vermeiden
Andere Tipps
Die Leistungseinbußen kommt von der Notwendigkeit einer Typprüfung Laufzeit. Wenn B eine Unterklasse von A ist, dann, wenn Sie ein B in einen Gipsverband, wissen Sie bei der Kompilierung, dass es sicher ist, da alle Bs As sind. Daher brauchen Sie keinen Laufzeitcode zu erzeugen, um den Typen zu überprüfen.
Wenn Sie jedoch ein A in ein B gegossen, Sie wissen nicht, zum Zeitpunkt der Kompilierung, ob die A tatsächlich ein B ist oder nicht. Es könnte nur ein A sein, könnte es vom Typ C sein, ein anderer Subtyp A. Daher müssen Sie Runtime-Code erzeugen, der das Objekt sicher machen ist eigentlich ein B und eine Ausnahme auslösen, wenn es nicht ist.
Generics haben dieses Problem nicht, da der Compiler weiß, bei der Kompilierung, dass nur Bs in die Datenstruktur gesetzt wurden, so dass, wenn Sie etwas aus, der Compiler ziehen weiß, dass es ein B sein, so gibt es keine müssen für die Typprüfung zur Laufzeit.