用if-else语句替换程序中switch语句
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了用if-else语句替换程序中switch语句相关的知识,希望对你有一定的参考价值。
参考技术A if(op=='+') printf(....);else if(op=='-') printf(....);
else if(op=='*') printf(....);
...
else if(op=='%') printf(....);本回答被提问者采纳
switch 语句中的 String 如何比相应的 if-else 语句更有效?
【中文标题】switch 语句中的 String 如何比相应的 if-else 语句更有效?【英文标题】:How is String in switch statement more efficient than corresponding if-else statement? 【发布时间】:2014-04-02 08:56:54 【问题描述】:Java documentation 说
Java 编译器从使用 String 对象的 switch 语句生成的字节码通常比从链式 if-then-else 语句生成的字节码更有效。
AFAIK 甚至 String in switch 在内部以区分大小写的方式使用.equals()
。那么在这种情况下,它们意味着什么效率。编译速度更快?更少的字节码?性能更好?
【问题讨论】:
帮助链接:blackwasp.co.uk/SpeedTestIfElseSwitch.aspx 顺便说一句,向所有人道歉;我显然是在昨晚睡着的时候写的,只是没有连接到基于散列的调度表。是的,这很有意义,不仅适用于非整数值,而且适用于宽间距的稀疏值。 “注意:为避免名誉受损,请先动脑筋再动手。” 【参考方案1】:使用 switch 语句比 equals 更快(但仅在有多个字符串时才明显),因为它首先使用switch
所在字符串的hashCode
来确定可以可能匹配。如果case标签中有多个字符串具有相同的hashCode,JVM会依次调用equals
,即使case标签中只有一个字符串是hashCode,JVM也需要调用equals
来确认case 标签中的字符串确实等于 switch 表达式中的字符串。
在 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;
【讨论】:
他们也可以使用 trie 实现 更多关于内部编译的细节在这里:docs.oracle.com/javase/specs/jvms/se7/html/…【参考方案2】:在一般中,switch 语句更好,因为它们(粗略地说)是O(1)
,而if-else
的链是O(n)
拥有n
条件可能会导致使用链式if-else
语句进行最多n
比较。
switch 语句可以直接“跳转”到适当的条件(如地图)或默认情况,使其成为O(1)
。
【讨论】:
根据@Erwin Bolwidt 提供的解释,这是有道理的。【参考方案3】:这是从文档中的示例生成的字节码片段:
INVOKEVIRTUAL java/lang/String.hashCode ()I
LOOKUPSWITCH
-2049557543: L2
-1984635600: L3
-1807319568: L4
与 if-else 逻辑相比,使用 LOOKUPSWITCH 具有更好的性能
【讨论】:
LOOKUPSWITCH 是一直存在的字节码指令。当它打开的整数值相距很远时,使用它代替 TABLESWITCH。正如您在程序集中看到的,它不会打开字符串本身,而是打开字符串的 hashCode。您还需要在 L2、L3 或 L4 显示字节码:您会看到需要调用 String.equals 来验证字符串是否真的相同。 @ErwinBolwidt 但有趣的是,TABLESWITCH 不一定是它听起来的样子:在默认设置下,在 17 种情况下,它在汇编中被转换为 cmp/je 序列(即 if/goto)。拥有18个或更多的案例,它也成为了组装级别的真正的表开关。 有趣。还注意到(至少)Eclipse 编译器不会发出 TABLESWITCH,即使您打开带有连续哈希码(“A”、“B”、“C”等)的字符串。以上是关于用if-else语句替换程序中switch语句的主要内容,如果未能解决你的问题,请参考以下文章
switch 语句中的 String 如何比相应的 if-else 语句更有效?
switch语句和switch-case与if-else之间的转换