switch语句中的String如何比相应的if-else语句更有效?
Java文档说
Java编译器通过使用String对象的switch语句而不是链式的if-then-else语句生成通常更有效的字节码。
AFAIK甚至string切换使用.equals()
在内部以区分大小写的方式。 那么在这种情况下他们的含义是什么? 编译速度更快? less了字节码? 更好的性能?
使用switch语句比equals语句更快(但只有当有多个string时才显着),因为它首先使用打开的string的hashCode
来确定可能匹配的string的子集。 如果case标签中的多个string具有相同的hashCode,则JVM将执行对equals
连续调用,即使在case标签中只有一个string是一个hashCode,JVM需要调用equals
来确认string在case标签真的等于switchexpression式中的标签。
String对象上的开关的运行时性能与HashMap
的查找相当。
这段代码:
public static void main(String[] args) { String s = "Bar"; switch (s) { case "Foo": System.out.println("Foo match"); break; case "Bar": System.out.println("Bar match"); break; } }
内部编译并像这样的代码执行:
(不是字面意思,但是如果你反编译这两个代码片段,你会发现完全相同的动作序列)
final static int FOO_HASHCODE = 70822; // "Foo".hashCode(); final static int BAR_HASHCODE = 66547; // "Bar".hashCode(); public static void main(String[] args) { String s = "Bar"; switch (s.hashCode()) { case FOO_HASHCODE: if (s.equals("Foo")) System.out.println("Foo match"); break; case BAR_HASHCODE: if (s.equals("Bar")) System.out.println("Bar match"); break; } }
一般来说 ,switch语句更好,因为它们(松散地说)是O(1)
,而if-else
的链是O(n)
有n
条件可能导致多达n
比较使用链接的if-else
语句。
switch语句可以直接跳转到适当的条件(如地图)或默认情况下,使其成为O(1)
。
这是从文档中的示例生成的字节码片段:
INVOKEVIRTUAL java/lang/String.hashCode ()I LOOKUPSWITCH -2049557543: L2 -1984635600: L3 -1807319568: L4
与if-else逻辑相比,使用LOOKUPSWITCH具有更好的性能