【问题标题】:if-else optimization & gotchas?if-else 优化和陷阱?
【发布时间】:2013-12-31 11:12:50
【问题描述】:

我在下面有两个简单的 sn-ps 代码。片段 1 没有 else 条件。从逻辑上讲,两个 sn-ps 都有相同的目的。

如果我要在程序中的两个 sn-ps 之间进行选择,我想知道是否有任何问题或优化改进?

片段 1

public boolean isOauthTokenValid(long oauthExpiryTimestamp){

    if (oauthExpiryTimestamp >= System.currentTimeMillis()){
        return true;
    }

    return false;
}

片段 2

public boolean isOauthTokenValid(long oauthExpiryTimestamp){

    if (oauthExpiryTimestamp >= System.currentTimeMillis()){
        return true;
    }
    else {
        return false;
    }
}

这会在字节码级别进行优化吗?

【问题讨论】:

  • 它会在字节码级别提供任何性能改进吗?或者只是增加可读性
  • if (…) return true else return false; 毫无意义。只需return …;
  • 提防过早优化 -
  • 谨防使用“过早优化”一词来阻止人们思考事情的实际运作方式
  • 没有“字节码级别的性能改进”之类的东西,除非你故意关闭 JVM 优化——在这种情况下你显然不关心性能。

标签: java optimization if-statement


【解决方案1】:

完全不用if。您可以直接使用比较的结果:

return (oauthExpiryTimestamp >= System.currentTimeMillis());

【讨论】:

  • 谢谢!当谈到编程风格时,不使用这个成语是我最大的烦恼之一。
【解决方案2】:

更简单:

return oauthExpiryTimestamp >= System.currentTimeMillis();

通过这种方式,您可以避免在代码中使用条件。但无论如何,性能提升将是微不足道的。

为什么会这样?因为如果条件中的布尔表达式为true,则返回true,如果为false,则返回false - 所以返回布尔表达式的值就足够了。

【讨论】:

  • @TitoCheriachan “也许”。它取决于静态编译器,无论如何 JIT 编译器可能会在运行时将其优化为相同的代码。这里重要的是两个版本在语义上是等效的,而且使用任何一个版本所获得的性能差异可以忽略不计。更重要的是编写易于阅读的代码,而不是担心如此微小的微优化
【解决方案3】:

回答问题本身,两个给定的 sn-ps 被编译为相同的字节码,但与 @rgettman 和 Óscar López 建议的简洁版本不同。

private final Random r = ThreadLocalRandom.current();

private boolean test() {
    return r.nextBoolean();
}

boolean full() {
    if (test()) {
        return true;
    } else {
        return false;
    }
}

boolean part() {
    if (test()) {
        return true;
    }
    return false;
}

boolean id() {
    return test();
}

结果:

        boolean full();
        Code:
        0: aload_0
        1: invokespecial #2                  // Method test:()Z
        4: ifeq          9
        7: iconst_1
        8: ireturn
        9: iconst_0
        10: ireturn

        boolean part();
        Code:
        0: aload_0
        1: invokespecial #2                  // Method test:()Z
        4: ifeq          9
        7: iconst_1
        8: ireturn
        9: iconst_0
        10: ireturn

        boolean id();
        Code:
        0: aload_0
        1: invokespecial #2                  // Method test:()Z
        4: ireturn

但是,所有版本在 Hotspot JVM 上的性能完全相同。

【讨论】:

    【解决方案4】:

    一个好的编译器会产生等效的字节码。

    在这种情况下,您应该以可读性为指导(请参阅有关完全删除条件的其他答案)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-12-08
      • 2020-11-23
      • 2015-04-15
      • 2023-03-28
      • 2010-12-29
      • 1970-01-01
      • 2011-05-18
      • 2021-09-22
      相关资源
      最近更新 更多