Effizienz des Methodenaufrufs für die Schleifenbedingung

8

Ich schreibe eine Game-Engine, in der eine Menge von Objekten, die in ArrayList gehalten werden, mithilfe einer for-Schleife durchlaufen werden. Offensichtlich ist die Effizienz ziemlich wichtig, und deshalb habe ich mich über die Effizienz der Schleife Gedanken gemacht.

%Vor%

Wo getSupportedExtension() eine ArrayList von String s zurückgibt. Ich frage mich, ob die Methode jedes Mal aufgerufen wird, wenn die Schleife über eine neue Erweiterung iteriert. Wenn ja, wäre es effizienter, etwas zu tun wie:

%Vor%

? Vielen Dank im Voraus.

    
Isaac Woods 30.03.2015, 10:54
quelle

3 Antworten

8

Nach Spezifikation, das Idiom

%Vor%

expandiert nach

%Vor%

Daher tritt der Aufruf, den Sie fragen, nur einmal bei der Schleifeninitialisierungszeit auf. Es ist das Iterator-Objekt, dessen Methoden wiederholt aufgerufen werden.

Wenn Sie jedoch ehrlich an der Leistung Ihrer Bewerbung interessiert sind, sollten Sie sicherstellen, dass Sie sich auf die großen Gewinne und nicht auf kleine Kartoffeln wie diese konzentrieren. Es ist fast unmöglich, einen Getter-Call als Flaschenhals in irgendeinem Code hervorzuheben. Dies gilt für Anwendungen, die auf HotSpot ausgeführt werden, doppelt, wodurch der Getter-Aufruf in einen direkten Feldzugriff umgewandelt wird.

    
Marko Topolnik 30.03.2015, 10:57
quelle
2

Nein, die Methode assetLoader.getSupportedExtensions() wird nur einmal vor der ersten Iteration der Schleife aufgerufen und dient zum Erstellen einer Iterator<String> , die von der erweiterten for-Schleife verwendet wird.

Die beiden Snippets haben die gleiche Leistung.

    
Eran 30.03.2015 10:55
quelle
1
  1. Direkte Kosten.

Da, wie die Leute schon sagten, das folgende

%Vor%

verwandelt sich in

%Vor%

getSupportedExtensions () wird einmal aufgerufen und beide Code-Snippets haben die gleichen Leistungskosten, aber nicht die bestmögliche Leistung, um die Liste zu durchlaufen, wegen ...

  1. Indirekte Kosten

Welches sind die Kosten der Instanziierung und Nutzung des neuen kurzlebigen Objekts + Kosten der Methode next (). Method iterator () bereitet eine Instanz von Iterator vor. Es ist also notwendig, Zeit zu investieren, um das Objekt zu instanziieren und dann (wenn dieses Objekt unerreichbar wird) es zu GC zu machen. Die gesamten indirekten Kosten sind nicht so viel (etwa 10 Anweisungen zum Zuweisen von Speicher für neues Objekt + einige Anweisungen des Konstruktors + etwa 5 Zeilen ArrayList.Itr.next () + Entfernen des Objekts aus Eden auf kleinere GC), aber ich persönlich bevorzuge Indizierung (oder sogar einfache Arrays):

%Vor%

über Iteration, wenn ich die Liste häufig im Hauptpfad meiner Anwendung durchlaufen muss. Einige andere Beispiele für Standard-Java-Code mit versteckten Kosten sind einige String-Methoden (substring (), trim () usw.), NIO-Selektoren, Boxen / Unboxing von Primitiven, um sie in Sammlungen usw. zu speichern.

    
AnatolyG 08.04.2015 15:45
quelle

Tags und Links