【问题标题】:java using logical operators instead of if-else if for returnjava使用逻辑运算符而不是if-else if for return
【发布时间】:2011-10-02 00:02:51
【问题描述】:

我在 equals 方法中有以下代码。

public boolean equals(Object o){
    if (o == null) return false;
    if (o == this) return true;
    if (!(o instanceof Vertex)) return false;
    return ((Vertex) o).label().equals(label);
}

我的 IDE 突出显示 if 语句并希望我基本上这样做

public boolean equals(Object o){
    return (o != null) && ((o==this) || ((o instanceof Vertex) && ((Vertex) o).label().equals(label);
}

有人告诉我,编译器通常足够聪明,可以进行优化,而且通常应该编写代码以提高可读性。因此,显然第二个代码示例不像第一个那样容易阅读。我的 IDE 只是烦人,还是这样做有一些实际的性能优点?

【问题讨论】:

    标签: java conditional return logical-operators


    【解决方案1】:

    首先,只有在您知道这是一个瓶颈时才进行优化,否则代码是为了提高可读性。

    您可以检查字节码以查看,但我怀疑它们非常接近,如果不完全相同的话。即使字节码略有不同,我也看到 JIT 编译器将内容优化到没有差异的地方。您可以随时进行性能测试来确定。

    【讨论】:

    • 对不起,你能解释一下如何检查字节码吗?我是新手,自学,所以我只需键入代码并在 IDE 中按运行。
    • @jbhu87:查看 javap 和 jad。
    【解决方案2】:

    大多数 IDE 都是可配置的,并允许您指定它输出的样式警告类型。您是正确的,就生成的代码而言,按照编译器的建议去做没有任何好处。编译器确实应该能够优化这些东西。

    【讨论】:

      【解决方案3】:

      您的 IDE 建议的版本的性能优势几乎没有。此外,你说得对,JVM(不仅仅是编译器)可以做很多优化。

      正如其他人指出的那样,尽量达到可读性。你写的代码是由人类阅读,由Java编译器和虚拟机编译、修改和优化的。

      顺便说一句。一个简短的提示:您的代码可以像这样优化一点(省略等于null 的条件,因为o 保证在第二个条件之后是 Vertex 的实例):

      public boolean equals(Object o){
          if (o == this) return true;
          if (!(o instanceof Vertex)) return false;
          return ((Vertex) o).label().equals(label);
      }
      

      【讨论】:

        【解决方案4】:

        不要试图让编译器变得聪明。您正在编写代码供人阅读。让编译器担心将其转换为机器可读的格式。

        【讨论】:

          【解决方案5】:

          这样做的好处是,如果您内联代码,那么您可以轻松地将其分配给布尔值,但您也可以使用三元运算符使其更具可读性,这将比优化版本更具可读性,但具有相同的功能,如果您以后学习如何操作,可能会帮助您简化编码。

          public boolean equals(Object o){
              return o == null || !(o instance of Vertex) ? false :
                 o == this ? true :
                 ((Vertex) o).label().equals(label);
          }
          

          这应该仍然是可读的。

          我没有尝试编译这个,可能需要一些额外的括号,但我要的是一个概念,而不是你可以复制和粘贴的东西。

          【讨论】:

          • 虽然这更容易阅读,但它并不是很容易阅读。 if-then 风格比这个简单多了
          • @HXCaine - 但是,正如我提到的,学习这种风格还有其他好处,否则您将 if 语句放入函数中,或者在每个步骤中设置一个变量。最终,这个结构非常有用。
          【解决方案6】:

          为什么不测试自己的表现呢?这是一个示例:

          public static long timeIt(Runnable runnable) {
              long start = System.nanoTime();
              runnable.run();
              long end = System.nanoTime();
              return end - start;
          }
          

          将为您计时运行方法。所以你可以这样称呼它:

          timeIt(new Runnable() { public void run() { OPERATION_TO_BE_TIMED; }})
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2011-09-06
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多