4

ソースコードは次のとおりです。

public int indexOf(Object o) {
    if (o == null) {
        for (int i = 0; i < size; i++)
            if (elementData[i]==null)
                return i;
    } else {
        for (int i = 0; i < size; i++)
            if (o.equals(elementData[i]))
                return i;
        }
    }
    return -1;
}

これを 1 つにしない理由: ループと if ステートメントは 1 つだけです。

public int indexOf(Object o) {

   for (int i = 0; i < size; i++){
       if (o == null) {
             if (elementData[i]==null)
                return i;
        else {
             if (o.equals(elementData[i]))
                return i;
        }
    }

    return -1;
}

最初のスニペットには 2 つのループが必要ですが、上記のコードのパフォーマンスは優れていると言う人もいます。なんで?

4

4 に答える 4

4

事実上、両方のスニペットは同じことをします。ただし、最初のスニペットでの単一の比較だけではなく、比較ステートメントが複数回評価されるため、2番目のスニペットのパフォーマンスが低下する可能性があります。各コードスニペットが通過するループの反復回数は同じですが、必要な比較の回数は異なります。そのような単純な。

于 2012-09-01T01:26:17.303 に答える
0

考え方は、最初のものは1回だけ比較するo必要nullがあり、2番目のものはループ内の各パスでそれを比較する必要があるということです。

于 2012-09-01T01:26:19.240 に答える
0

単一のループでは、反復ごとに条件を再チェックする必要があります。したがって、より多くの作業が必要になります。

最初の例では、条件を1回だけチェックします。

(文字通りの方法で)最適化せずにコンパイルした場合、2番目の例は遅くなります。

ただし、ほとんどのコンパイラにはトリックがあり、2番目の例のコードを最初の例と同等のマシンコードに変換できます。ただし、これはコンパイラの最適化フラグ(つまり、最適化されるもの-実行時間またはコードサイズ)に大きく依存します。

于 2012-09-01T01:26:49.533 に答える
0

o == null2番目のフォームは、size - 1回数が少ないかどうかをチェックします。

とにかくそのような最適化があなたのために行われていないと仮定します。それを試さずに想定することはありません。

ループ内の最終的なマシンコードに含まれる命令が少ないことにも利点がある場合がありますが、違いが生じる可能性はほとんどありません。

可能なブランチの数を減らすと、誤った命令がプリフェッチされる可能性が低くなるため、パフォーマンスも向上します。(Andreas Henningに感謝します)。

全体として、ループの外に物事を移動するという考えは、何かを最適化する必要があるときに行うのに十分合理的なことですが、この場合はおそらく問題にならないでしょう。

あなたのコメントを見るだけです。ArrayList.indexOfにヒットするコードの量を考えると、考えられるすべての小さなスクイーズを実行するのに適した場所です。

于 2012-09-01T01:30:58.830 に答える