Eine Sache habe ich noch vergessen, zu erwähnen: Falls alle diese oben genannten Performanceoptimierungen nicht greifen, und der statische Typ des zugegriffenen List-Objektes nur java.util.List ist, gibt es dann ja die Situation, dass der java.util.List.get(int) Aufruf ein Interfacemethodenaufruf ist. Das bedeutet, hier muss die JVM intern schauen, was denn der tatsächliche Typ des dahinterliegenden Objektes ist, um die implementierte/überschriebene get() Methode zu findet. Das heißt, hier gibt es single dynamic dispatch.
ABER: Die JVM ist natürlich hier auch schlau. Zwei Dinge passieren:
- Einmal: Inline Caching
- Und: Vermeidung von dynamic dispatch, wenn die einzige gerade geladene Klasse, die java.util.List implementiert, die des Objektes ist, auf dem der Aufruf passiert. In diesem Fall wird der Aufruf ein direkter Methodenaufruf werden, bei dem dann auch wieder alle obig genannten Optimierungen greifen. Da vermutlich aber immer mehr als eine Klasse in der JVM geladen ist, die java.util.List implementiert (meist interne Klassen), ist das eher ein Fall, der zumindest für java.util.List nicht eintritt.
Bei Inline Caching wird die Aufrufstelle so transformiert, dass nur geprüft werden zu braucht, ob bei jedem zukünftigen Aufruf der Typ des Objektes immer noch derselbe ist, wie bei den letzten Aufrufen, und es braucht kein dynamic dispatch lookup stattfinden. Das ist sehr sehr häufig der Fall. In diesem Fall ist dann nur ein object.getClass() == oldClass Test (der sehr sehr schnell ist) nötig, und falls die Bedingung erfüllt ist, wird ein direkter (nicht-virtueller, also ohne dynamic dispatch) Aufruf auf die get() Methode gemacht.
Aber in diesen ganzen Fällen kann man schon sagen, dass rein theoretisch die get()-Methode langsamer ist, als der C/C++ Indexoperator. Aber das wird man zur Laufzeit kaum spüren. Insbesondere, wenn der Code etwa in einer Schleife ausgeführt wird, da die Speicherzugriffslatenzen zum RAM und das Füllen der CPU Caches größer sein werden als das tatsächliche Fetching, Decoding und Ausführen der Instruktionen der get() Methode.