Ich war gespannt, wie Java und Scala Schalter auf Strings implementieren:einschalten Strings
class Java
{
public static int java(String s)
{
switch (s)
{
case "foo": return 1;
case "bar": return 2;
case "baz": return 3;
default: return 42;
}
}
}
object Scala {
def scala(s: String): Int = {
s match {
case "foo" => 1
case "bar" => 2
case "baz" => 3
case _ => 42
}
}
}
Es scheint, wie Java-Schalter auf der Hash-Code und führt dann einen einzelnen String-Vergleich:
0: aload_0
1: dup
2: astore_1
3: invokevirtual #16 // Method java/lang/String.hashCode:()I
6: lookupswitch { // 3
97299: 40
97307: 52
101574: 64
default: 82
}
40: aload_1
41: ldc #22 // String bar
43: invokevirtual #24 // Method java/lang/String.equals:(Ljava/lang/Object;)Z
46: ifne 78
49: goto 82
52: aload_1
53: ldc #28 // String baz
55: invokevirtual #24 // Method java/lang/String.equals:(Ljava/lang/Object;)Z
58: ifne 80
61: goto 82
64: aload_1
65: ldc #30 // String foo
67: invokevirtual #24 // Method java/lang/String.equals:(Ljava/lang/Object;)Z
70: ifne 76
73: goto 82
76: iconst_1
77: ireturn
78: iconst_2
79: ireturn
80: iconst_3
81: ireturn
82: bipush 42
84: ireturn
Im Gegensatz dazu scheint Scala gegen alle Fälle zu vergleichen:
0: aload_1
1: astore_2
2: ldc #16 // String foo
4: aload_2
5: invokevirtual #20 // Method java/lang/Object.equals:(Ljava/lang/Object;)Z
8: ifeq 16
11: iconst_1
12: istore_3
13: goto 47
16: ldc #22 // String bar
18: aload_2
19: invokevirtual #20 // Method java/lang/Object.equals:(Ljava/lang/Object;)Z
22: ifeq 30
25: iconst_2
26: istore_3
27: goto 47
30: ldc #24 // String baz
32: aload_2
33: invokevirtual #20 // Method java/lang/Object.equals:(Ljava/lang/Object;)Z
36: ifeq 44
39: iconst_3
40: istore_3
41: goto 47
44: bipush 42
46: istore_3
47: iload_3
48: ireturn
Kann man Scala davon überzeugen, den Hashcode-Trick anzuwenden? Ich würde lieber eine O (1) Lösung zu einer O (n) Lösung bevorzugen. In meinem echten Code muss ich mit 33 möglichen Keywords vergleichen.
Ich glaube nicht, dass Java dies die ganze Zeit tun wird, was ist die Garantie, dass alle angegebenen Strings unterschiedliche Hashcodes haben? Diese Überprüfung wird wahrscheinlich im Interpreter (JVM) durchgeführt und wählt nur die Hashcode-Lösung aus, wenn alle Strings zu einem eindeutigen Hash-Wert ausgewertet werden. – smac89
@ Smac89 Hash-Kollisionen sind überhaupt kein Problem. Java wird einfach zur selben Stelle springen und dann 2 String-Vergleiche anstelle von 1 durchführen. Außerdem kennt der Compiler alle Strings und somit alle ihre Hashcodes. Die JVM muss die Situation nicht dynamisch analysieren. – fredoverflow
Ich bin auch neugierig ... ist Scala immer noch nützlich, jetzt, da Java 8 draußen ist? –