2016-07-04 10 views
7

Gibt es einen guten Grund (Performance-weise) eine ersetzen:Ist eine Instanz val teurer als das Companion-Objekt val?

val SOME_CONST = "value"

mit

companion object { 
    val SOME_CONST = "value" 
} 

Hat das Hinzufügen einer @JvmStatic Anmerkung ändert das Ergebnis?

+0

Sie können ein eigenständiges Objekt für Konstanten verwenden, nicht unbedingt einen Begleiter;) – voddan

Antwort

12

Ja, ein val gespeichert in companion object ist effizienter. Sie können Kotlin bytecode viewer verwenden, um herauszufinden, wozu diese Optionen kompiliert werden.

Hier sind die Dinge, die ich bemerkt, dass die Leistung beeinträchtigen könnten:

  • Companion Objekt val wird nur einmal gespeichert sind, im Gegensatz zu Beispiel val, die tatsächlich in jedem Fall gespeichert wird, damit die Instanzen Speicherbedarf (String wörtliche Erhöhung is stored in constant pool, aber eine Instanz hat einen Verweis darauf) und Instanzerstellungszeit (während der Konstruktion muss ein Feld ausgefüllt werden).

  • Zugriff auf Companion-Objekt val mehrmals hintereinander funktioniert besser mit CPU-Cache als mit val in verschiedenen Instanzen: es hat bessere locality of reference. Das Dereferenzieren verschiedener Instanzen, um auf die val in ihnen zuzugreifen, führt wahrscheinlich zu CPU-Cache-Misses, die für die Leistung nicht gut sind.

    Wenn der val jedoch nur innerhalb von Instanzmethoden der gleichen Klasse verwendet wird, beeinträchtigt der beschriebene Effekt die Leistung kaum, da die Methoden wahrscheinlich sowieso deneferenzieren this, und dies kann sogar besser funktionieren und keinen wahrscheinlichen Cache-Fehler beim Zugriff verursachen das Begleitobjekt

  • Hinzufügen @JvmStatic macht den Zugriff ein bisschen schneller. Ohne es erfordert Zugriff auf den Wert statische Companion Referenz und Aufruf getSOME_CONST() darauf. Bei @JvmStatic gibt es die statische Methode getSOME_CONST() (überspringt Companion). Es gibt auch @JvmField, die ein öffentliches Feld macht, auf das direkt zugegriffen werden kann, ohne selbst Getter aufzurufen.

    Aber JIT-Compiler wird wahrscheinlich den Getter-Zugriff der ersten beiden Fälle optimieren, so dass der Effekt der Anmerkungen kaum wahrnehmbar sein wird.

Auch abgesehen von Leistung, Instanz val Semantik eines Wert hat, der für jede Instanz anders sein könnte, so companion object scheint besser, den Fall des globalen konstanten Wertes zu passen.