45 Stimmen

Warum verbessert die Definition einer Klasse als final die JVM-Leistung?

Zitiert von http://sites.google.com/site/gson/gson-design-document :

Warum sind die meisten Klassen in Gson als endgültig?

Gson bietet zwar eine ziemlich erweiterbare Architektur bietet, indem es einsteckbare Serialisierer und Deserialisierer bietet, wurden die Gson-Klassen nicht speziell entwickelt, um erweiterbar zu sein. Die Bereitstellung von nicht-finalen Klassen hätte es einem Benutzer ermöglicht Gson-Klassen rechtmäßig zu erweitern, und dann zu erwarten, dass dieses Verhalten in allen nachfolgenden Revisionen funktioniert. Wir haben uns entschieden solche Anwendungsfälle einzuschränken, indem wir die Klassen als endgültig markieren und warten, bis ein ein guter Anwendungsfall auftaucht, um die Erweiterbarkeit. Die Kennzeichnung einer Klasse als final hat auch den kleinen Vorteil, dass es zusätzliche Optimierungsmöglichkeiten für den Java-Compiler und die virtuelle Maschine.

Warum ist dies der Fall? [Wenn ich raten würde: weiß die JVM, dass eine Klasse final ist, und pflegt keine Tabellen mit Methodenüberschreibungen? Gibt es noch andere Gründe?]

Worin besteht der Leistungsvorteil?

Gilt dies für Klassen, die häufig instanziiert werden (POJO?) oder vielleicht für Klassen, die statische Methoden besitzen (Utility-Klassen)?

Können als endgültig definierte Methoden theoretisch auch die Leistung verbessern?

Gibt es irgendwelche Auswirkungen?

Ich danke Ihnen, Maxim.

44voto

TofuBeer Punkte 59410

Virtuelle (überschriebene) Methoden werden im Allgemeinen über eine Art Tabelle (vtable) implementiert, die letztlich ein Funktionszeiger ist. Jeder Methodenaufruf hat den Overhead, dass dieser Zeiger durchlaufen werden muss. Wenn Klassen als final gekennzeichnet sind, können alle Methoden nicht mehr überschrieben werden, und die Verwendung einer Tabelle ist nicht mehr erforderlich - das macht sie schneller.

Einige VMs (wie z.B. HotSpot) können intelligenter vorgehen und wissen, wann Methoden überschrieben werden bzw. nicht überschrieben werden dürfen und generieren entsprechend schnelleren Code.

Aquí finden Sie einige genauere Informationen über HotSpot. Und einige general Informationen zu.

19voto

andersoj Punkte 21576

Eine alte, offenbar nicht mehr aber noch weitgehend relevanter Artikel von IBM zu diesem Thema developerWorks in der es heißt:

Die allgemeine Auffassung ist, dass Klassen oder Methoden als endgültig zu deklarieren macht es dem Compiler leichter, Methodenaufrufe Methodenaufrufe zu inlinen, aber diese Wahrnehmung ist jedoch falsch (oder zumindest zumindest stark überbewertet).

finale Klassen und Methoden können ein erhebliche Unannehmlichkeiten bei der Programmierung - sie schränken Ihre Möglichkeiten für die Wiederverwendung von bestehendem Code und Erweiterung der Funktionalität von bestehenden Klassen. Während manchmal eine Klasse aus einem guten Grund endgültig gemacht wird, z.B. um Unveränderlichkeit zu erzwingen, ist die Vorteile der Verwendung von final sollten die Unannehmlichkeiten überwiegen. Leistungsverbesserung ist fast ist fast immer ein schlechter Grund, gute objektorientierten Entwurfsprinzipien zu gefährden, und wenn die Leistungsverbesserung gering oder gar nicht vorhanden ist, ist dies ein schlechter Kompromiss in der Tat.

Siehe auch dies verwandte Antwort auf eine andere Frage . Außerdem gibt es die Äquivalente Frage für .Net, hier diskutiert . SO Diskussion, " Sind finale Methoden inlined ?" Zu einer Frage mit dem Titel " Welche Optimierungen werden morgen nutzlos sein? ", steht auf der Liste.

Es ist auch zu beachten, dass es eine Verflechtung der Auswirkungen von final Klassen vs. final Methoden. Sie Mai einen gewissen Leistungsvorteil (auch hier habe ich keine gute Referenz) für final Methoden sicher, da sie könnte veranlassen das JIT zum Inlining, das es sonst nicht (oder nicht so einfach) durchführen könnte. Den gleichen Effekt erzielen Sie, wenn Sie die Klasse final , was bedeutet, dass alle Methoden plötzlich auch endgültig sind. Beachten Sie, dass die Sun/Oracle-Leute behaupten, dass HotSpot dies normalerweise mit oder ohne die final Stichwort. Gibt es irgendwelche zusätzlich Auswirkungen, die sich daraus ergeben, dass die Klasse selbst final ?

Als Referenz finden Sie Links zu den JLS auf letzte Methoden y letzte Klassen .

1voto

Michael Goldshteyn Punkte 68533

Ohne die Implementierung jeder einzelnen JVM zu kennen, würde ich theoretisch sagen, dass, wenn eine JVM weiß, dass ein Zeiger auf ein Objekt ein Zeiger auf einen Typ ist, der endgültig ist, sie nicht-virtuelle Funktionsaufrufe (d.h. direkt vs. indirekt) auf eine Mitgliedsfunktion durchführen kann (d.h. keine Umleitung durch einen Funktionszeiger), was zu einer schnelleren Ausführung führen kann. Dies kann auch zu Möglichkeiten des Inlinings führen.

1voto

LorenVS Punkte 12187

Die Kennzeichnung von Klassen als endgültig ermöglicht weitere Optimierungen während der JIT-Phase.

Wenn Sie eine virtuelle Methode in einer nicht-finalen Klasse aufrufen, wissen Sie nicht, ob die korrekte Implementierung die in dieser Klasse definierte ist, oder eine Unterklasse, die Sie nicht kennen.

Wenn Sie jedoch einen Verweis auf eine endgültige Klasse haben, kennen Sie die spezifische Implementierung, die erforderlich ist.

Bedenken Sie:

A extends B
B extends C

B myInstance = null;
if(someCondition)
   myInstance = new B();
else
   myInstance = new C();
myInstance.toString();

In diesem Fall kann das JIT nicht wissen, ob die Implementierung von toString() von C oder die Implementierung von toString() von B aufgerufen wird. Wenn jedoch B als endgültig markiert ist, ist es unmöglich, dass eine andere Implementierung als die von B die richtige Implementierung ist.

0voto

Stas Punkte 1668

Kein Unterschied, das ist reine Spekulation. Die einzige Situation, wo es Sinn hat, sind Klassen wie String, etc, wo JVM sie anders behandeln.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X