为什么单个“if”比“switch”慢?

12

可能是重复问题:
Java 中 if/else 和 switch 语句的相对性能差异是什么?

下面给出两个方法:

public static int useSwitch(int i) {
    switch (i) {
    case 0:
        return 1;
    default:
        return 0;
    }
}

public static int useIf(int i) {
    if (i == 0)
        return 1;
    return 0;
}

测试表明,在我的计算机上,switch 的执行速度略快于 if 版本,每次调用快 1.4 纳秒。

我一直以为只有避免几个 if 才能发挥 switch 的好处,

为什么 switch 比单个 if 更快?


4
你知道它们被编译后长什么样吗?也许你可以在那里找到答案。 - user1306322
2
@user1306322- 你需要更深入地了解JVM如何解释或编译字节码。第一段代码可能会使用lookupswitchtableswitch指令,而第二段则会使用普通跳转。让它们快速运行完全取决于JVM。 - templatetypedef
3
你能发布你的基准测试代码吗? - Patricia Shanahan
@PatriciaShanahan 测试代码比较 nanoTime() 对于 for (int i = 0; i < 999999; i++) x += useIf(i) (x 被断言)。 - Bohemian
请查看此链接:https://dev59.com/AXI95IYBdhLWcg3w7StZ#2086550 - gefei
显示剩余2条评论
2个回答

7

通过检查字节码,结果如预期:

开关

public static useSwitch(I)I
 L0
  ILOAD 0
  TABLESWITCH
    0: L1
    default: L2
 L1
  INVOKESTATIC Tests.a()I
  IRETURN
 L2
  INVOKESTATIC Tests.b()I
  IRETURN

如果

public static useIf(I)I
 L0
  ILOAD 0
  IFNE L1
 L2
  INVOKESTATIC Tests.a()I
  IRETURN
 L1
  INVOKESTATIC Tests.b()I
  IRETURN

现在我并没有看到任何特别的原因,可以使其中一个比另一个慢(在任何情况下都不会有明显的差异)。这肯定与具体的JVM实现以及它如何执行这些操作码有关。根据常识,TABLESWITCH指令应该比较慢,除非有足够的情况使其构造有价值,但这只是常见思考。每个JVM可能会以不同的方式实现它,因此这只是猜测。

您确定已经以一致的方式对所有内容进行了分析吗?(通过给JVM留出时间来热身,通过保持只有在置信范围内的结果以及所有其他使分析足够正确以便使用的事项)


我必须承认,在多次运行测试后,“有时候”if比switch更快。您关于没有特定原因的评论反映了我在进一步测试中发现的情况。 - Bohemian

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接