2013-05-24 10 views
5

Niederwerfung Lets wir drei übernehmen (oder mehr) KlassenCasting Leistung in verschiedenen Ebenen, wenn

public class A {}

public class B erstreckt A {}

public class C B erstreckt implementiert G {}

Angenommen, jede Klasse hat ihre eigenen 20 (oder mehr) Methoden.

Hat das Gießen nach C vs Gießen nach A größere Auswirkungen auf die Leistung? Wie funktioniert Java Casting unter der Haube?

Muss es beim Ablegen nach allen Methoden und Feldern auf Anwesenheit durch Reflexion prüfen?

Bearbeiten: Beeinträchtigt die Größe der Klassen (Anzahl der Felder und Methoden) die Leistung beim Casting? Ich interessiere mich für beide OpenJRE und Dalvik.

Für die Referenz weiß ich, dass Upcasting ohne Probleme durchgeführt werden kann.

Antwort

3

Die Leistung des Castings hängt von der JVM-Implementierung ab.

Die JLS 5.5 bestimmt nur die Anforderungen für das Casting (die einen rekursiven Algorithmus enthält), legt jedoch keine Anforderungen an die Implementierung fest. Tatsächlich sind die runtime cast rules in 5.5.3 auch auf die gleiche Weise bestimmt. Alle JVM-Implementierungen, die das gleiche Ergebnis wie der vorgeschlagene Algorithmus erzeugen, werden als geeignete JVM akzeptiert.

Im Allgemeinen dauert die Umwandlung auf C ein wenig länger, da die JVM den Laufzeittyp des Objekts untersuchen muss. Beim Gießen bis A hat es keinen Grund, die gleiche Prüfung zu machen, da BA verlängert.

Tatsächlich interessiert sich die JVM nicht für die Anzahl der Methoden und Felder. Es vergleicht nur die Typenhierarchie, die gleichen man mit Reflexion untersuchen (o.getClass())

I einen Beispielcode wie folgt, eine niedergeschlagene, dann einer upcast:

Object o = new Integer(1); 
Integer i = (Integer) o; 

Object o2 = i; 

Der kompilierte Bytecode ist die folgende:

0 new java.lang.Integer [16] 
3 dup 
4 iconst_1  <-- 1 as a parameter to the constructor 
5 invokespecial java.lang.Integer(int) [18] <-- constructor 
8 astore_1 [o]  <-- store in 'o' 
9 aload_1 [o] 
10 checkcast java.lang.Integer [16] <-- DOWNCAST CHECK, SPECIAL BYTECODE 
13 astore_2 [i] 
14 aload_2 [i] 
15 astore_3 [o2] <-- WITH UPCAST NO CHECK 

So gibt es eine bestimmte JVM Anweisung, die das Element auf der Oberseite des Stapels mit einer bestimmten Klasse überprüft.

Mit upcast wird überhaupt keine Prüfung durchgeführt.

Die Größe der Klassen (Anzahl der Felder, Methoden tatsächlichen Fußabdruck) hat keine Rolle, denn das Gießen der Class untersucht (die Metadaten, die eigentlich ein Objekt ist).

Die Anzahl der Hierarchieebenen und die Anzahl, wenn implementierten Schnittstellen (wenn an einem Interface Guss) nicht egal, weil das der verfahrbaren Vererbungs/implementation Baum ist zu überprüfen.

Ich wäre überrascht, wenn es keine Art von Cache für diese Prüfung geben würde.

+0

"Da die JVM den Laufzeittyp des Objekts untersuchen muss", wie wird es untersucht? –

+0

Danke, wäre großartig, wenn Sie mir in kurzen Worten sagen könnten, welche Art von Operationen isAssignableForm tut? Es ist schwierig, diese Art von Quellcode zu analysieren. –

+1

Eigentlich habe ich mich geirrt, die Wahrheit ist noch nativer als 'isAssignableFrom()' – gaborsch

1

Eine detaillierte Architektur von checkcast in HotSpot (die in anderer Antwort als JVM Mechanismus für Downcasting erwähnt wurden), werfen Sie einen Blick auf dieser Konferenz Papier:

Fast subtype checking in the HotSpot JVM

ein Zitat aus der Zusammenfassung:

in aktuellem Benchmark läuft unsere Technik Kontrollen in 3 Anweisungen (nur 1 Speicherreferenz) im wesentlichen alles Zeit komplett Subtyp führt. In seltenen Fällen wird auf einen langsameren Array-Scan zurückgegriffen. Speicher Verwendung ist moderat (6 Wörter pro Klasse) und kann für die Zeit aus gehandelt werden.

Also, wenn Sie nicht einige sehr Low-Level-Code mit viel Casting schreiben, sind die Auswirkungen vernachlässigbar.