2015-04-23 10 views
6

Offenbar sind when Ausdrücke zusammengestellt unterschiedlich, je nachdem, wie man Konstanten bezeichnet:Effizienter Switch braucht Selbstqualifizierung?

object SwitchOverConstants { 
    val foo = 1 
    val bar = 2 
    val baz = 3 

    fun one(x: Int) = when (x) { 
     foo -> "foo" 
     bar -> "bar" 
     baz -> "baz" 
     else -> "else" 
    } 

    fun two(x: Int) = when (x) { 
     SwitchOverConstants.foo -> "foo" 
     SwitchOverConstants.bar -> "bar" 
     SwitchOverConstants.baz -> "baz" 
     else -> "else" 
    } 
} 

Hier ist der Byte-Code für one:

0: iload_1  
    1: istore_2  
    2: iload_2  
    3: getstatic  #15     // Field foo:I 
    6: if_icmpne  14 
    9: ldc   #34     // String foo 
    11: goto   40 
    14: iload_2  
    15: getstatic  #22     // Field bar:I 
    18: if_icmpne  26 
    21: ldc   #35     // String bar 
    23: goto   40 
    26: iload_2  
    27: getstatic  #27     // Field baz:I 
    30: if_icmpne  38 
    33: ldc   #36     // String baz 
    35: goto   40 
    38: ldc   #38     // String else 
    40: areturn  

Und hier ist der Byte-Code für two:

0: iload_1  
    1: tableswitch { // 1 to 3 
       1: 28 
       2: 33 
       3: 38 
      default: 43 
     } 
    28: ldc   #34     // String foo 
    30: goto   45 
    33: ldc   #35     // String bar 
    35: goto   45 
    38: ldc   #36     // String baz 
    40: goto   45 
    43: ldc   #38     // String else 
    45: areturn  

Wie kommt es, ich muss die Konstanten mit dem Klassennamen zu qualifizieren eine effiziente Tabellensuche erhalten?

+2

Dies ist ein Bild der Implementierung im Compiler. Nicht genau ein Fehler, aber wir werden es wahrscheinlich bald (auf die eine oder andere Weise) beheben. –

+0

Zugehöriges Problem: [KT-7579] (https://youtrack.jetbrains.com/issue/KT-7579) – bashor

+0

Dies ist eher eine Bug- oder Feature-Anfrage als eine SO-Frage. Es funktioniert am besten als ein Problem in [YouTrack] (https://youtrack.jetbrains.com) und war nett von @Bashor, um ein Problem zu erstellen, das es für Sie verfolgt. –

Antwort

0

Sie sollten jede Konstante mit const Modifizierer markieren, dann wird die Optimierung passieren.

Übrigens ist in der neuesten Version von Kotlin der Bytecode für beide Funktionen identisch.