java - 在 Java 中 : do expressions involving constants defined at instantiation get simplified during compile-time?

标签 java optimization compiler-construction constants compile-time

正如我在标题中总结的那样,我想知道涉及在实例化时定义的常量的表达式是否会在编译时得到简化?

例如,我有一个堆类,其中有一个最终 boolean 值 isMinHeap,其值在堆的构造函数中设置。堆的方法然后在某些地方使用这个 boolean 值。编译器可以优化它以简化所有这些涉及此 boolean 值的表达式,还是每次调用方法时都计算完整的表达式?

谢谢!

编辑: 因为有人问我一个更具体的例子,这里有一个方法,每次从堆中移除一个节点时都会调用(以协助重新堆化树):

private boolean requiresRepositioningDown(BTNode<T> node)
{
    boolean childIsSmaller = (node.getLeft().getValue().compareTo(
            node.getValue()) < 0)
            || (node.getRight() != null && node.getRight().getValue().compareTo(
                    node.getValue()) < 0);
    if (isMinHeap && childIsSmaller || !isMinHeap && !childIsSmaller)
        return true;
    else
        return false;
}

这里带有 isMinHeap 的表达式似乎每次都会得到完整的计算,而如果堆在实例化时被设为最大堆,则可以(并且应该)忽略表达式的整个右侧。

最佳答案

很可能不会。首先,它在编译时仍然不是常量;仍然有两个不同的例子。这种优化通常留给 JIT 编译器。

即使您的常量从未设置为任何其他值,也不会对其进行优化。例如

public class Heap {
    final boolean isMinHeap;
    public Heap() {
        isMinHeap = true;
    }
    @Override
    public String toString() {
        if (isMinHeap) return "Min!";
        return "Not Min";
    }
}

编译为

  public java.lang.String toString();
    Code:
       0: aload_0
       1: getfield      #2                  // Field isMinHeap:Z
       4: ifeq          10
       7: ldc           #3                  // String Min!
       9: areturn
      10: ldc           #4                  // String Not Min
      12: areturn

请注意,条件仍然存在。如果经常使用该方法,JIT 编译器可能会选择完全删除它,因为它应该知道 final 成员不能更改。但这有点难以观察。

如果您立即将 isMinHeap 设置为一个值,而不是在构造函数中执行此操作,然后将执行优化:

public class Heap {
    final boolean isMinHeap = true;
    public Heap() {
    }
    @Override
    public String toString() {
        if (isMinHeap) return "Min!";
        return "Not Min";
    }
}

toString 编译为:

  public java.lang.String toString();
    Code:
       0: ldc           #3                  // String Min!
       2: areturn

关于java - 在 Java 中 : do expressions involving constants defined at instantiation get simplified during compile-time?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11590517/

相关文章:

java - 中介和 CustomEventBanner java

java - 二维整数数组的 Arrays.sort 失败

javascript - 编译 RequireJS 去除 AMD 依赖

gcc - 我想要 __builtin_popcountll 的两种实现

c++ - 如何使用我的 LLVM 中的现有函数传递 - 传递?

java - Java 中的 Hankaku 到 Zenkaku,反之亦然

java - 无法 Autowiring javamailSender

Python正确使用scipy.optimize.minimize

python - 使用 numpy 加速 for 循环

parsing - 不仅对表达式使用优先级解析器?