2016-01-08 6 views
5

sagen, dass ich den folgenden Code haben:Gibt es eine Leistung Kosten Autobox ein primitives Literal?

Map<String, Boolean> map = ... 
map.put("foo", true); 

Theoretisch true wird in einer leichten Performance im Vergleich Einfügen Boolean.TRUE treffen müssen autoboxed werden, zur Folge hat. Aber da es sich um einen Literalwert handelt, ist es möglich, dass der Compiler das primitive Literal durch ein Boxed-Literal ersetzt, so dass es keinen zusätzlichen Laufzeitaufwand gibt.

Bevor irgendjemand mich angreift, würde ich mich im Allgemeinen für das einfache Literal entscheiden, um die Klarheit des Codes zu gewährleisten, selbst wenn es kleine Performance-Kosten gibt. Diese Frage ist meist theoretisch.

+0

Der Schlüssel zum Verstehen einer performancebezogenen Frage beginnt immer mit einem Test. Zeigen Sie zur Verbesserung Ihrer Frage einen Zeittest, der Ergebnisse einer Leistungsanalyse enthält. Zum Beispiel könnten Sie eine zeitgesteuerte for-Schleife schreiben, die 100K Einträge in eine Map einfügt und die Länge der Map ausdruckt, und dasselbe für verschiedene Argumente zu 'map.put' tun. – activedecay

+0

Sie können eine 'Boole'-Konstante verwenden; 'map.put (" foo ", Boolean.TRUE);' –

+0

@ElliottFrisch Ich weiß. Meine Frage ist, ob es überhaupt helfen würde. – shmosel

Antwort

4

Ja, es gibt einen kleinen Leistungseinbruch. Um ein Grundelement zu boxen, wird die Methode valueOf() des Wrappertyps verwendet. Da dies eine so einfache Methode für Boolean (return x ? TRUE : FALSE;) ist, könnte ein JIT das Ergebnis effektiv inline darstellen; Derzeit ist der Java-Compiler jedoch nicht. (Die Verwendung von valueOf() wird von der JLS nicht benötigt, daher könnte eine Optimierung für eingeführt werden.)

Für andere Typen ist es komplizierter. Beispiel: Integer gibt zwischengespeicherte Instanzen für Werte nahe Null zurück und erstellt neue Instanzen für größere Werte. Optimierungen können zwar weiterhin durchgeführt werden, aber die Zuweisung einer neuen Instanz dauert immer etwas Zeit.


In Reaktion auf die Kommentare, lassen Sie mich auf das konzentrieren, was ich nahm der entscheidende Punkt der Frage zu sein:

, da wir mit einer wörtlichen Wert zu tun hat, ist es möglich, dass der Compiler die primitive wörtlichen mit einem boxed wörtlichen

zu ersetzen Ja, es ist möglich, aber keine, wird der Oracle javac Compiler nicht t tun seine.

Spielt es eine Rolle? Nein, der Performance-Hit für das Boxen auf ist infinitesimal; Boxen boolean mit der gleichen valueOf() Technik als andere Primitive ist eine sichere und vernünftige Wahl für den Compiler.

+0

Ich würde mich wundern, wenn das JIT nicht in der Lage wäre, beide Optionen im Wesentlichen gleichwertig zu machen. Ihr erster Satz ist vielleicht zu kategorisch. – assylias

+0

@assylias Ich würde mich auch wundern, aber würde das beim ersten Lauf passieren? Selbst wenn das der Fall wäre, würde dieser Optimierungsprozess mehr Zeit in Anspruch nehmen als Code, der 'Boolean.TRUE' anstelle von' true' verwendet? – erickson

+3

Ich denke, der entscheidende Punkt ist, dass der Haupt-Performance-Hit entsteht, wenn ein * neues Objekt * zugewiesen werden muss. Im Fall von Boolean.valueOf() wird ein neues Objekt niemals zugewiesen. Der Code sollte wirklich die Klassenkonstante Boolean.TRUE anstatt des Booleschen Grundliterals verwenden, aber ich würde erwarten, dass die tatsächliche Leistungsdifferenz zwischen den beiden in diesem Fall immeasurely klein ist, – scottb

Verwandte Themen