java if else string_关于java:switch语句中的String如何比相应的if-else语句更有效?

Java文档说

The Java compiler generates generally more efficient bytecode from switch statements that use String objects than from chained if-then-else statements.

AFAIK even String in switch在内部使用.equals()以区分大小写的方式。 那么它们在这种背景下的效率是多少。 编译速度更快? 字节码少? 更好的性能?

有用的链接:blackwasp.co.uk/SpeedTestIfElseSwitch.aspx

顺便说一下,向所有人道歉; 我昨晚睡着了,显然是在写一个基于哈希的调度表的连接。 是的,这非常有意义,不仅适用于非整数值,还适用于宽间距稀疏值。"注意:为了避免损害声誉,请在将手指放入装备前进行大脑活动。"

使用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/

通常,switch语句更好,因为它们(松散地说)是O(1),而if-else的链是O(n)

具有n条件可能导致使用链式if-else语句进行最多n次比较。

switch语句可以直接"跳转"到适当的条件(如地图)或默认情况下,使其成为O(1)。

根据@Erwin Bolwidt提供的解释,这是有道理的。

这是从docs中的示例生成的字节码片段:

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编译器即使在您使用连续的hashCodes("A","B","C"等)切换字符串时也不会发出TABLESWITCH。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值