Java:在这里包括其他更快的?还是更好的练习?

时间:2012-03-07 01:53:07

标签: java optimization

在诸如下面的java片段中的那个情况下,使用else块来包围返回false与使用else块之后的更快或更好的练习是不是更快或更好?

public boolean test(boolean var){
    if (var == true){
        return true;
    }
    return false;
}

相比
public boolean test(boolean var){
    if (var == true){
        return true;
    }else{
        return false;
    }
}

显然这是一个非常简单的例子,可以缩短为一行,但我的问题是是否有一个jvm优化,这使得在第二个片段中使用else块更有效,或者是否更好的练习,因为两者都是片段在逻辑上是等价的。到目前为止,我一直在使用第一个代码段,因为代码少了一些。

6 个答案:

答案 0 :(得分:13)

我编译了两个示例,结果字节码相同:

  public boolean test(boolean var);
    0  iload_1 [var]
    1  ifeq 6
    4  iconst_1
    5  ireturn
    6  iconst_0
    7  ireturn
      Line numbers:
        [pc: 0, line: 5]
        [pc: 4, line: 6]
        [pc: 6, line: 8]
      Local variable table:
        [pc: 0, pc: 8] local: this index: 0 type: scratch.Else1
        [pc: 0, pc: 8] local: var index: 1 type: boolean

  public boolean test(boolean var);
    0  iload_1 [var]
    1  ifeq 6
    4  iconst_1
    5  ireturn
    6  iconst_0
    7  ireturn
      Line numbers:
        [pc: 0, line: 5]
        [pc: 4, line: 6]
        [pc: 6, line: 8]
      Local variable table:
        [pc: 0, pc: 8] local: this index: 0 type: scratch.Else2
        [pc: 0, pc: 8] local: var index: 1 type: boolean

至于你应该使用哪一个?在这个人为的例子中,答案是响亮的。与行为匹配的最佳代码是:

public boolean test(boolean var){
    return var;
}

考虑到“if {return} else {return}”与“if {return} return”的选择,我的回答通常是后者,因为我更喜欢缩进。但我认为这实际上取决于每个分支中的代码数量。如果代码指向前者,则更多其他代码指向后者。

答案 1 :(得分:6)

它们完全一样。像这个现代编译器这样的小东西会为你优化,javac就是这样做的。考虑以下课程:

public class IsElseFaster {
    public boolean test1(boolean var) {
        if (var == true) {
            return true;
        }
        return false;
    }

    public boolean test2(boolean var) {
        if (var == true) {
            return true;
        } else {
            return false;
        }
    }
}

复制并粘贴到您喜欢的编辑器中,使用javac进行编译。然后运行javap -c IsElseFaster 您将获得以下输出:

public boolean test1(boolean);

  Code:
   0:   iload_1
   1:   iconst_1
   2:   if_icmpne   7
   5:   iconst_1
   6:   ireturn
   7:   iconst_0
   8:   ireturn

public boolean test2(boolean);
  Code:
   0:   iload_1
   1:   iconst_1
   2:   if_icmpne   7
   5:   iconst_1
   6:   ireturn
   7:   iconst_0
   8:   ireturn

正如您所看到的那样,当您到达.class文件时,这些方法完全相同。

答案 2 :(得分:2)

这非常属于个人风格,不同的人会给你不同的意见;没有一个正确的答案。在性能方面,没关系;编译器将优化它们完全相同(我只是通过实验测试了这一点)。

就个人而言,我认为额外的else更漂亮。不过,这可能是我的功能编程背景。

答案 3 :(得分:0)

就您提供的确切代码段而言:

  • 编译器会将两个版本优化为完全相同的字节码,因此没有性能差异

  • 在风格方面,没有普遍认同的规则。有些团队倾向于将else留出,因为它是多余的,其他人更愿意将其包括在内,因为它更能代表您的意图。我个人倾向于包括else,因为它捕获了意外错误。

例如:

public Object foo(int i) {
  if(i > 0) {
     this.someMethod(); // !! Opps forgot to "return" here.
  }
  return this.anotherMethod(); // This method always returns 'anotherMethod'
}

编辑:我错过了我的第一个版本的最终回复,我想这有助于证明我的观点;)

如果那里有elseelse return this.anotherMethod()),那么编译器会给出一个错误,即第一个分支永远不会返回一个值。所以我发现将else置于适当位置有助于发现错误。

在更一般的情况下(关于是否包含else),将会出现编译器无法像在简单示例中那样轻松优化它的情况。在这种情况下,省略else将产生更少的字节码指令,但是否更快将取决于您运行的JVM,JIT和CPU。

这些优化非常很少值得担心 - 总是与你(以及你的团队伙伴)认为哪些代码更易读和可维护。

答案 4 :(得分:-1)

第一个更好,因为其他没有必要。你永远不想在设计中包含不必要的部分,无论是java程序还是汽车或其他东西。

更新:

必要性并不意味着普通意义上的功利主义。例如,如果多余的是用于深度防御或美学防御,那么它就没有必要了。理解发布的问题的例子很简单,下面是一个例子,其中不必要的其他因素会使设计复杂化,因为需要额外的return语句。

public static int add(int a, int b){
    if(a > 0){
        int c = a+b;
        return c;
    } else if( a<= 0){
        int c = a-(-b);
        return c;
    }
}

bty:虽然这个例子将论证简化为荒谬,但它说明了不必要的部分。

答案 5 :(得分:-1)

第一个更好,因为如果你可以删除多个退出点,即只有一个return或尽可能少,那么它会更漂亮,你可以在这里做一个。

另请使用codereview.stackexchange.com查看评论类型问题。

public boolean test(boolean var){
    boolean flag;
    if (var == true){
        flag = true;
    }
    return flag;
}