6

質問する前に、理由もなく最適化についての講義を受けないようにお願いできますか。次の質問は純粋に学術的なものと考えてください。

私はJavaのルート(つまり、頻繁に使用され、頻繁に相互にアクセスする)クラス間のアクセスの効率について考えてきましたが、これはほとんどのオブジェクト指向言語/コンパイラに当てはまります。Javaで何かにアクセスできる最速の方法(私が推測している)は、静的な最終参照です。理論的には、その参照はロード中に利用できるため、優れたJITコンパイラーは、変数にアクセスするために参照ルックアップを実行する必要をなくし、その変数へのアクセスを定数アドレスに直接向けます。おそらくセキュリティ上の理由から、とにかくそのようには機能しませんが、私に耐えてください...

起動時に渡す操作の問題や引数があると判断したとしましょう。つまり、各クラスが他のクラスをそのまま構築するという問題に直面したとしても、静的な最終参照を取得することはできません。 Javaクラスが相互に静的な最終参照を持つようにすることをお勧めします。これを実行したくないもう1つの理由は、たとえば、これらのクラスのいくつかのプラットフォーム固有の実装を提供していたことです。;-)

今、私には2つの明白な選択肢が残されています。すべてのクラスを構築した後に設定される静的参照(一部のシステムハブクラス上)を使用して、クラス間で相互に認識させることができます(この間、クラスはまだ相互にアクセスできないため、操作の順序の問題は解消されます。少なくとも建設中)。一方、クラスは相互にインスタンスの最終参照を持つことができます。操作の順序を整理することが重要であるか、引数を渡す人の責任にすることができるか、またはそれ以上のことを提供することを決定した場合、これらのクラスのプラットフォーム固有の実装は、相互に参照する必要があります。

静的変数は、それが属するクラスに対して変数wrtの場所を検索する必要がないことを意味し、1つの操作を節約します。最後の変数は、値を検索する必要はまったくないが、クラスに属している必要があることを意味するため、「1つの操作」を保存します。OK、私は今本当に手振りをしていることを知っています!

次に、別のことが起こりました。静的な最終スタブクラスを作成できました。これは、スタブを拡張できる「impl」に各呼び出しが降格される、奇抜なインターフェイスのようなものです。その場合、パフォーマンスに影響を与えるのは、関数を実行するために必要な二重関数呼び出しであり、メソッドをfinalとして宣言することはもうできないと思います。適切に宣言されていればインライン化できるのではないかと仮定し、'impl'への参照を静的、最終、または...にすることができるかどうかを考えなければならないことに気付いたので、あきらめました。

では、3つのうちどれが最も速くなるでしょうか?:-)

頻繁にアクセスするオーバーヘッドを減らすことや、JITコンパイラのパフォーマンスを示唆する他の方法について他に考えたことはありますか?

更新:さまざまなもののテストを数時間実行し、http://www.ibm.com/developerworks/java/library/j-jtp02225.htmlを読んだ後、C++などのチューニング時に通常見るもののほとんどが見つかりました。 JITコンパイラーを使用してウィンドウを完全に終了します。30秒の計算を1回、2回実行し、3回目(およびそれ以降)の実行で「ねえ、あなたはその計算の結果を読んでいないので、実行していません!」と判断するのを見ました。

FWIWでは、データ構造をテストでき、マイクロベンチマークを使用して、ニーズに対してよりパフォーマンスの高い配列リストの実装を開発することができました。アクセスパターンは、コンパイラが推測し続けるのに十分ランダムである必要がありますが、それでも、より単純でより調整されたコードを使用して、ジェネリック化された成長配列をより適切に実装する方法がわかりました。

ここでのテストに関する限り、ベンチマーク結果を得ることができませんでした。関数を呼び出し、最終オブジェクト参照と非最終オブジェクト参照から変数を読み取るという私の簡単なテストでは、JVMのアクセスパターンよりもJITについて多くのことが明らかになりました。信じられないことに、メソッド内の異なる場所にある同じオブジェクトで同じ関数を呼び出すと、4倍の時間がかかります

IBMの記事に載っている人が言うように、最適化をテストする唯一の方法はその場でです。

途中で私を指さしてくれたみんなに感謝します。

4

3 に答える 3

1

静的フィールドは、そのクラスの静的フィールドを含む特別なクラスごとのオブジェクトに格納されていることに注意してください。オブジェクトフィールドの代わりに静的フィールドを使用する方が速くなる可能性はほとんどありません。

于 2011-03-04T13:03:48.317 に答える
1

アップデートを参照してください。ベンチマークを実行して自分の質問に答えたところ、予期しない領域ではるかに大きな向上が見られ、メンバーの参照などの単純な操作のパフォーマンスは、CPUよりもメモリ帯域幅によってパフォーマンスが制限される最新のシステムで同等であることがわかりました。サイクル。

于 2011-06-22T12:01:59.053 に答える
0

アプリケーションを確実にプロファイリングする方法を見つけたとすると、別のjdk impl(IBMからSun、OpenJDKなど)に切り替えたり、既存のJVMのバージョンをアップグレードしたりすると、すべてがウィンドウから消えることに注意してください。

問題が発生し、JVMの実装が異なると結果が異なる可能性がある理由は、Java仕様にあります。これは、最適化を定義せず、各実装に最適化(または最適化しない)を任せることを明示的に示しています。実行動作は最適化によって変更されません。

于 2011-04-14T01:44:41.897 に答える