0

アイデアの完全に単純化された例として、次のコードを検討してください。

public class Main {
    public static void foreach(int[] x, intVoid action) {
        for (int i = 0; i < x.length; ++i) {
            action.apply(x[i]);
        }
    }

    public static void main (String[] args) {
        int[] h = new int[] {2, 3, 5, 7, 11, 13};
        for (int i = 0; i < 10; ++i) {
            foreach(h, new intVoid() {
                public void apply(int x) {
                    System.out.println(x * 2);
                }
            });
        }
    }
}

interface intVoid {public void apply(int x);}

for ループでforeachは、インターフェイスの匿名実装はコンテキスト内の何にも依存しないため、論理的な観点からは完全に同一の引数で呼び出します。問題は、インスタンス化されるのは 10 回か、それとも 1 回だけかということです。または、同様に、次のコードと同等になります。

public class Main {
    public static void foreach(int[] x, intVoid action) {
        for (int i = 0; i < x.length; ++i) {
            action.apply(x[i]);
        }
    }

    public static void main (String[] args) {
        int[] h = new int[] {2, 3, 5, 7, 11, 13};
        intVoid action = new intVoid() {
            public void apply(int x) {
                System.out.println(x * 2);
            }
        };
        for (int i = 0; i < 10; ++i) {
            foreach(h, action);
        }
    }
}

interface intVoid {public void apply(int x);}

私は、必要な場所に実装を正確に定義することが非常に便利な状況に陥ることがありましたが、同じオブジェクトを複数回作成しようとしないことを確認する必要がある場合もあります。ランタイムに最適化がある場合、これがさまざまな実装でどのように処理されるかに興味があります。特に、そのようなコードを変換して Android の Dalvik VM で実行するとどうなるかが気になります。
私はこれをすべて自分でテストできることを知っていますが、誰かがこの質問にすでに光を当てているかどうか疑問に思っています.

4

2 に答える 2

4

問題は、インスタンス化されるのは 10 回か、それとも 1 回だけかということです。

10回、それはあなたがそうするように言ったからです。applyJVM (または Dalvik)が、オブジェクトに副作用がなく、オブジェクトに状態がなく、したがって個別のインスタンスを作成する必要がないことに気付いたことに驚きました。それは可能です- Hotspot はかなり印象的です - しかし、私には最適化の可能性が低いように思えます。

もちろん、各オブジェクトを作成するのはおそらく安価ですが、2 番目のコード スニペットのように 1つのオブジェクトを作成する方がよいでしょう。

于 2013-01-23T09:05:09.420 に答える
3

実行されるたびにインスタンス化さnewれます。JIT された後、たとえば 10,000 回後にエスケープ分析によって削除される可能性がありますが、そうであるとは思いません。

個別のインスタンスを作成しないほどスマートな場合は、それを排除するほどスマートな方が優れています。

于 2013-01-23T09:05:02.610 に答える