27

これら 2 つの方法で効率 (実行時間、コード サイズなど) に違いはありますか?

以下は、オブジェクトを作成して何もしない不自然な例ですが、私の実際のシナリオでは、新しいスレッド、リスナーなどを作成している可能性があります。違いが生じる可能性があるように、次のコードがループで発生すると仮定します。

匿名オブジェクトの使用:

void doSomething() {
    for (/* Assume some loop */) {
        final Object obj1, obj2; // some free variables

        IWorker anonymousWorker = new IWorker() {
            doWork() {
                // do things that refer to obj1 and obj2
            }
        };
    }
}

最初にクラスを定義する:

void doSomething() {
    for (/* Assume some loop */) {
        Object obj1, obj2;
        IWorker worker = new Worker(obj1, obj2);
    }
}

static class Worker implements IWorker {
    private Object obj1, obj2;
    public CustomObject(Object obj1, Object obj2) {/* blah blah */}

    @Override
    public void doWork() {}
};
4

6 に答える 6

43

匿名クラスと最上位クラスの唯一の実質的な違いは、匿名クラスが外部クラスへの暗黙的な参照を保持することです。

これはパフォーマンスには現れませんが、これらのクラスをシリアライズすると影響を受けます。

于 2010-06-12T10:40:19.013 に答える
20

パフォーマンスの違いはほとんどないはずです。差があれば気にならないレベルです。

IMO、読みやすく保守しやすいコードを書くことに集中し、アプリケーションのプロファイリングに基づいて重要であるという明確な証拠が得られるまで、「マイクロ」パフォーマンスの問題を無視する必要があります。

(記録として、匿名の内部クラスが外側のfinalスコープ内の a を参照する場合、これは隠しコンストラクター引数と隠しインスタンス属性によってバイトコード レベルで実装されます。バイトコードは、取得したバイトコードとほぼ同じになります。他の実装。)

于 2010-06-12T10:37:44.887 に答える
18

匿名クラスは、コンパイル時に既知で完全にコンパイルされたクラスであることを理解することが重要です。たとえば、おそらくループ内に多くのメソッドやフィールドなどを含む匿名クラス本体を定義しているという事実は、ランタイムがすべての反復でその型をコンパイルする必要があるという意味ではありません。

したがって、2 つのアプローチのパフォーマンスの違いはごくわずかです。考慮すべき重要な要素は、読みやすさ、再利用性、テスト容易性などです。

于 2010-06-12T10:47:56.187 に答える
5

匿名クラスの多くのインスタンスをインスタンス化すると、パフォーマンスが大幅に低下することに実際に気付きました。

ローカルクラスが静的であることが原因であるかどうかを考えて、それを削除しましたが、違いはありませんでした。

私の場合、1000 を 3 回選択して 499,500 を実行していました。ローカル クラス (静的であるかどうかに関係なく) を使用したバージョンは 26 秒かかり、匿名の機能的に同一のクラスを使用したバージョンは 2 分 20 秒かかりました。

于 2013-05-15T17:21:00.653 に答える
0

コードのパフォーマンスについて推測することは、時間を無駄にする優れた方法です。実際にコードをベンチマークすることに匹敵するものはありません。パフォーマンスが心配な場合は、コードを測定してください。コードが最適化されていないと思われる場合は、コードをプロファイリングして時間が費やされている場所を特定し、それらの部分を改善してみてください。この時点で、実際にバイト コードを調べて、どの実装がより効率的かのヒントが得られるかどうかを確認することが適切な場合があります。

それが終わったら、コードをもう一度測定して、コードを醜くして保守を難しくするなど、事態を悪化させていないことを確認します。

于 2010-06-12T10:49:53.693 に答える