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

Which combination of switch and if/else is faster and why?

我有两套条件。一个有两个可能的值,另一个有更多(在这个例子中我写了 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 个案例。)

提前致谢!

Which code runs faster and is less error prompt (more accurate)?

答案:在这个具体案例中,性能不是问题。因为无论您将如何使用此实际执行数字都是相同的。但是你可以提高代码的可读性,让它更不容易出错。

与其担心性能,不如从 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);
}

这是一个微优化示例,可能对您的代码没有影响,因此 'which is faster' 在这里并不重要。

如果您想找出您的代码库中的哪些特定案例组合,那么您可能想使用像 JMH 这样的基准测试工具来找出哪个更适合你。但除非此代码位于关键路径上,否则它不会产生任何影响。

代码需要是:

  1. 正确
  2. 可读
  3. 高效

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

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

最终,写它是为了 readability/maintainability 而不是性能,直到你能证明这是在热循环上,然后明确地测量它。

还有一个选项:

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

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