1

私のタイトルに要約されているように、インスタンス化時に定義された定数を含む式がコンパイル時に単純化されるかどうか疑問に思っていましたか?

たとえば、ヒープのコンストラクターで値が設定されている最終的なブール値 isMinHeap を持つヒープ クラスがあります。ヒープのメソッドは、特定の場所でこのブール値を使用します。コンパイラはこれを最適化して、このブール値を含むこれらすべての式を単純化できますか、またはメソッドが呼び出されるたびに式が完全に計算されますか?

ありがとう!

編集:誰かがより具体的な例を求めたので、ノードがヒープから削除されるたびに呼び出されるメソッドを次に示します(ツリーの再ヒープ化を支援するため):

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 を使用した式は、毎回完全に評価されるように見えますが、ヒープがインスタンス化時に最大ヒープにされた場合、式の右側全体が無視される可能性があります (無視する必要があります)。

4

2 に答える 2

2

そうではない可能性が非常に高いです。まず第一に、コンパイル時のクラスではまだ一定ではありません。異なる場合が 2 つあります。そして、そのような最適化は通常、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
于 2012-07-21T08:08:47.607 に答える
1

元のソースからバイトコードへのコンパイラーは、実行時にしか分からない値を最適化できません。このような値は、用語の通常の使用では実際には「定数」ではありません。コンパイル時に単純化できる真の定数式は単純化されていると思います-したがって、次の場合:

public static final int FOO = 10;
public static final int BAR = 20;

...

System.out.println(FOO * BAR):

乗算はコンパイル時に実行されると思います。ただし、コンパイル時の定数ではないため、説明した場合は不可能です。

JIT コンパイラーは一般的な式を見つけることができるかもしれませんが、あらゆる種類の確実性を可能にするために、(単なる説明ではなくコードで) より具体的な例を提供する必要があります。

于 2012-07-21T08:10:35.470 に答える