2009-03-10 4 views
1

ich meinen Code profiliert und fand heraus, dass meine Klasse, die Comparable<T> implementiert, inDie Verbesserung Vergleichbare <T> compareTo Leistung

8x mehr CPU-Zeit verbringt
compareTo(Object) 

als in

compareTo(T) 

gehe ich davon aus, dass die Verlangsamung ist wegen der virtuellen Tabellensuche für diese Methode.


Gibt es eine Möglichkeit, den statischen Aufruf der Funktion zu erzwingen? (wie in nicht virtuellen C++ Methoden)

Ich möchte noch die Comparable<T> Schnittstelle verwenden, da ich TreeSet mit diesem Objekt verwenden, und ich möchte nicht diesen Code neu zu schreiben.


EDIT: Nein, ich habe nicht implementieren die compareTo (Object) - diese automatisch vom Profiler erzeugt und berichtet wurde

+0

Und die beiden compareTo's sind genau die gleichen als Gießen? –

+0

Lassen Sie uns die beiden Methoden sehen –

+0

Es wird in der Regel eine Bridging-Methode, wo compareTo (Object) ruft compareTo (ThisConcreteType). Vermutlich macht letzterer fast nichts. -server könnte Inline-Sachen helfen. –

Antwort

1

Da Java not preserve generische Typen zur Laufzeit der Fall ist, im Idealfall beide verhalten soll, das Gleiche. Wahrscheinlich gibt es noch etwas, das das Problem verursacht.

4

der Grund, warum Sie compareTo(Object) sehen, ist wegen Type Erasure. es bedeutet nur, dass zur Laufzeit die Typinformation zum Vergleichen der Werte nicht mehr benötigt wird. wahrscheinlich der Grund für Ihre Verlangsamung ist 1) sehr, sehr große TreeSet mit vielen Elementen 2) - eher - Ihre compareTo-Methode tut etwas teuer. weil es sehr oft aufgerufen wird (n * ln (n) mal typischerweise), sollte es effizient implementiert werden

+0

Ich verwende absichtlich ein großes TreeSet, und deshalb habe ich versucht, es so schnell wie möglich zu machen - es hat nur eine Dereferenzierung und zwei Vergleiche. – Dani

+1

Verwenden Sie TreeSet nur bei Bedarf. Wenn Sie Ihr Set nur zu bestimmten Zeiten sortiert haben, verwenden Sie HashSet und sortieren Sie es, wenn Sie es brauchen, nicht ständig. –

2

Nein, Sie können in diesem Fall keinen statischen Aufruf erzwingen.

Eine Instanzmethode kann durch die Anweisung invokespecial "nicht virtuell" aufgerufen werden. Diese Anweisung wird verwendet, wenn das Ziel zur Kompilierungszeit bekannt ist, wie ein Konstruktor oder eine private Methode. In anderen Fällen — selbst wenn die Zielmethode ist final — die invokevirtual oder invokeinterface Anweisungen verwendet werden.

+0

Punkt der Pedanterie: Oder wahrscheinlicher in diesem Fall, invokeinterface, als Vergleichbar ist eine Schnittstelle. –

0

Ich gehe davon aus, dass die Verlangsamung, weil der virtuellen Tabellen-Lookup für diese Methode.

Sie sollten nicht raten müssen, ob das wahr ist. Pausieren Sie einfach ein paar Mal, und Sie werden es auf frischer Tat ertappen. Zeigen Sie den Aufruf-Stack in seiner Gesamtheit an, einschließlich Aufrufe in Bibliotheksroutinen.

Meine Vermutung (was falsch sein könnte) ist, dass es durch neun Meter von OLE-Stil Invokation Hoo-Haw geht.

Verwandte Themen