switch 和 if/else 的哪个组合更快,为什么?

时间:2021-01-24 13:16:37

标签: java if-statement switch-statement compiler-optimization

我有两组条件。一个有两个可能的值,另一个有更多(在这个例子中我写了 3 个案例,但最多可能有 8 个)。哪些代码运行速度更快,错误提示更少(更准确)?

代码a)

if (letter.equals(a)) {
  switch (number) {

    case 1:
           .........
    case 2:
           .........
    case 3:
           .........
  }
} else if (letter.equals(b)) {
  switch (number) {

    case 1:
           .........
    case 2:
           .........
    case 3:
           .........
  }
}

代码 b)

switch (number) {

    case 1:

           if (letter.equals(a)) {
              .........
           } else if (letter.equals(b)) {
              .........
           }

    case 2:

           if (letter.equals(a)) {
              .........
           } else if (letter.equals(b)) {
              .........
           }

    case 3:

           if (letter.equals(a)) {
              .........
           } else if (letter.equals(b)) {
              .........
           }
  }

如果您认为除了这两个之外还有更好的选择,请告诉我。 (我也可以创建一个同时获取 letternumber 的参数,并使用它创建 6 个案例。)

先谢谢你!

3 个答案:

答案 0 :(得分:1)

<块引用>

哪些代码运行速度更快,错误提示更少(更准确)?

答案:在这种特定情况下,性能不是问题。因为无论你打算如何使用这个实际执行次数都是一样的。但是您可以提高代码的可读性并使其不易出错。

与其担心性能,不如从 SOLID 原则开始。你为什么不把这个大方法分解成一些具有具体责任的小方法。它将使代码更漂亮,更不容易出错。例如:

方法:

void processA(int number){
switch (number) {

    case 1:
           .........
    case 2:
           .........
    case 3:
           .........
  }
}

void processB(int number){
    
  switch (number) {

    case 1:
           .........
    case 2:
           .........
    case 3:
           .........
  }
}

///
now from the main method you could simply call:


if (letter.equals(a)) {
   // call the method which will process A
   processA(number);
} else if (letter.equals(b)) {
   // call the method which will process A
   processB(number);
}

答案 1 :(得分:1)

这是一个可能对您的代码没有影响的微优化示例,因此“哪个更快”在这里并不重要。

如果您想了解代码库中的哪种特定组合,那么您可能需要使用 JMH 等基准测试工具来确定哪种更适合您。但除非此代码位于关键路径上,否则它不会产生任何影响。

代码需要:

  1. 正确
  2. 可读
  3. 性能

关注 1 和 2 比关注最后一个要好得多。

在这种特殊情况下,在幕后的 JVM 中,切换数字可能更快,而切换表达式自然会涉及更多的分支跳转。因此,我天真地期望 switch-over-int-followed-by-if 会稍微偏向相反的方向,但如果没有证据,这将是一种预感,而不是可以依赖的东西。也很可能无论写什么基准测试都会有某种缺陷,例如 JVM 会自动将最佳测试用例组合提升到第一个测试,在这种情况下,它不会告诉你你认为它在做什么。

最终,编写它是为了可读性/可维护性而不是性能,直到你能证明这是在热循环中,然后明确地测量它。

答案 2 :(得分:0)

还有一个选择:

    switch (String.format("%1s%1d", letter, number) {
        case "a1": 
            ...
        case "b1":
            ...
        case "a2"
            ...
        case "b2":
            ...
        case "a3":
            ...
        case "b3": 
            ...
    }

更好?也许,也许不是。但它另一种选择...

相关问题