有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

Java编译器:“级联”ifs的优化和最佳实践?

Java编译器会优化这样的语句吗

if (a == true) {
 if (b == true) {
  if (c == true) {
   if(d == true) {
       //code to process stands here
   }
  }
 }
}

if (a == true && b==true && c==true && d == true)

所以这是我的第一个问题:这两个版本的“CPU周期”是完全相同的,还是第一个版本的“速度较慢”

我的第二个问题是,第一个变量的级联式编程风格是否被认为是糟糕的,因为它太冗长了

(我喜欢第一个变量,因为我可以更好地对表达式进行逻辑分组,并更好地对它们进行注释(我的if语句比示例中的更复杂),但这可能是糟糕的编程风格?)更慢的是,这就是为什么我要问

谢谢 詹斯


共 (3) 个答案

  1. # 1 楼答案

    第一个变体使在一个或多个条件上放置断点变得更容易,并且检查条件时抛出的任何异常的堆栈跟踪也将指示检查的是哪一行

  2. # 2 楼答案

    首先,不要使用a == TRUE

     if (a) { ... }
    

    其次,这样的代码:

    public class Test {
      public int f(boolean a, boolean b, boolean c, boolean d) {
        if (a && b && c && d) {
          return 1;
        } else {
          return 2;
        }
      }
    
      public int g(boolean a, boolean b, boolean c, boolean d) {
        if (a)
          if (b)
            if (c)
              if (d)
                return 1;
        return 2;
      }
    }
    

    被编译成(javap -c Test):

    public class Test extends java.lang.Object{
    public Test();
      Code:
       0:   aload_0
       1:   invokespecial   #1; //Method java/lang/Object."<init>":()V
       4:   return
    
    public int f(boolean, boolean, boolean, boolean);
      Code:
       0:   iload_1
       1:   ifeq    19
       4:   iload_2
       5:   ifeq    19
       8:   iload_3
       9:   ifeq    19
       12:  iload   4
       14:  ifeq    19
       17:  iconst_1
       18:  ireturn
       19:  iconst_2
       20:  ireturn
    
    public int g(boolean, boolean, boolean, boolean);
      Code:
       0:   iload_1
       1:   ifeq    19
       4:   iload_2
       5:   ifeq    19
       8:   iload_3
       9:   ifeq    19
       12:  iload   4
       14:  ifeq    19
       17:  iconst_1
       18:  ireturn
       19:  iconst_2
       20:  ireturn
    
    }
    

    正如你所看到的,字节码是相同的

    第三,这取决于问题,但通常过于冗长。如果您对这些细节发表评论:

    • 你的评论太冗长了。他们应该支持不复制它的代码(BAD:x = x + 1; // Increase x by 1)-可能汇编程序是唯一的例外,因为add rax, 1 ; Increase x by 1通知raxx
    • 你的代码做了一些可能不应该做的“聪明”的事情(尽管有些情况是合理的)
  3. # 3 楼答案

    Java“编译器”可能不会在这里进行任何优化(编译两者,并反编译它们以进行比较)。但是JVM运行时很可能会这样做

    然而,也就是说,这是一个微观优化;这样你的代码才是下一个开发者最容易理解的

    这里的最佳实践是最可读的代码

    当然,不要使用(xxx == true),这是一种可怕的做法,而是使用(xxx)