Java中switch case、else if性能比较

4,312 阅读2分钟
原文链接: mp.weixin.qq.com

背景:笔者在接收一个项目的时候,有段代码逻辑大致是把map转化成model的时候,需要遍历属性值(String)类型,用的是else if(大概有100+个属性值),代码如下:

看了这段代码我个人觉得用switch写可读性可能更好点,性能也可能会更好点,于是我就把他改成switch方式做了一下简单的测试,为了只是测试switch 和 else if的性能稍微把代码做了一下改动,代码如下:

在都运行100_000次的情况下,switch耗时160ms左右,else if 耗时在870ms左右,性能相差5倍左右。

为了搞清楚为什么相差这么多,反编译一下class文件,发现switch在定位的时候是二分查找(首先每个case 中String 计算出 hashcode,然后按照hashcode进行排序,再次定位case时使用二分查找,最后使用equals看是不是真的是该字段(主要hashcode相等并不一定就真的相等)),反编译的switch case部分代码如下:

而else if 反编译之后,发现就是一直在判断直到满足条件之后,判断结束。

从上面我们看出switch 对于String 使用的时间复杂度为O(log(n)),else if 为O(n),对于n比较大的时候应该是有性能提升的。

补充一下:其实对于这种情况完全可以使用枚举,其可读性和性能还能提升很多,因为jvm 对于 switch 这种情况下为进行优化,查找的时间复杂度提升到O(1),反编译之后一个字节码可以看出(是tableswitch字节码的时候为O(1),是lookupswitch 字节码的时候为O(log(n)))。具体可以参考:https://stackoverflow.com/questions/10287700/difference-between-jvms-lookupswitch-and-tableswitch