为什么开关比如果更快
我在java中发现很多书,switch语句比if语句更快。 但我没有findantwhere说为什么开关比如果更快 。
例
我有一个情况,我必须从两个select任何一个项目我可以使用以下任一方式
switch(item){ case BREAD: //eat Bread break; default: //leave the restaurant }
或使用if语句如下所示
if(item== BREAD){ //eat Bread }else{ //leave the restaurant }
考虑项目和BREAD是恒定的int值
在上面的例子中,行动更快,为什么?
因为有很多情况下有特殊的字节码可以进行有效的开关语句评估。
如果使用IF语句实现,您将有一个检查,跳转到下一个子句,检查,跳转到下一个子句等等。 使用开关,JVM加载要比较的值并遍历值表以find匹配,这在大多数情况下更快。
switch
语句并不总是比if
语句快。 它比if-else
语句长,因为switch
可以根据所有值执行查找。 但是,对于一个短的条件,它不会更快,可能会更慢。
在字节码级别,主体variables从运行时加载的结构化.class文件的内存地址中只加载一次到处理器寄存器中,并且在switch语句中; 而在if语句中,由代码编译DE产生不同的jvm指令,这要求将每个variables加载到寄存器中,尽pipe使用了与if语句的下一个前一个相同的variables。 如果你知道用汇编语言编码,那么这将是司空见惯的; 尽pipejava编译的coxes不是字节码,或者是直接的机器码,但是这里的条件概念仍然是一致的。 那么,我试图在解释时避免更深入的技术性。 我希望我已经使这个概念清楚和揭穿了。 谢谢。
如果你正在执行一个像100+的疯狂数量的检查,你可能要考虑一些抽象。
你有传入数据包范围从ids 0到255.你可能使用其中150个。 你可能想考虑下面的东西,而不是150个ID的开关。
Packets[] packets = new Packets[150]; static { packets[0] = new Login(); packets[2] = new Logout(); packets[3] = new GetMessage(); packets[7] = new AddFriend(); packets[9] = new JoinGroupChat(); // etc... not going to finish. } static final byte[] INDEX_LIST = { 0, 2, 3, 7, 9, // etc... Not going to do it, but this will convert packet id to index. }; public void handlePacket(IncomingData data) { int id = data.readByte(); packets[INDEX_LIST[id]].execute(data); }
我还应该指出,索引列表并不是真的需要,反正可能会减慢代码的速度。 这只是一个build议,所以你没有空位。 更不用说这种情况了,你只是在106个指标中失利了。 我不是100%肯定的,但我相信每个这些都指向无效,所以不存在真正的记忆问题。