6

条件に対して可能なオン/オフフラグを最速で提供する方法を探しています(つまり、ゼロタイム- コンパイル/クラスロード/JIT 時間の解決) 。もちろん、この条件は、アプリケーションの実行ごとに 1 回だけ変更されます (起動時)。if

「条件の場合のコンパイル時定数」は条件付きでコンパイルでき、条件全体をコードから削除できることを知っています。しかし、ソースを再コンパイルする必要のない最速の (そしておそらく単純な) 代替手段は何ですか?

.jar条件を単一のクラスと条件付きのメソッドで分離するように移動して、その 2 つのバージョンを生成.jarし、アプリケーションの起動時にクラスパスでそれらのバージョンを切り替えることはできますか? そのメソッドが空であることを発見した場合、JITは別のメソッドへの呼び出しを削除しますか?.jar

「ClassWithMyCondition」を実装するクラスパスに 2 つのクラスを提供することでそれを行うことができますか?これらのクラスの 1 つには実際の実装があり、2 つ目は空のメソッドのみを持ち、その 1 つをインスタンス化します。JIT はClass.forNameプライマリ.newInstance()から空のメソッドへの呼び出しを削除しますか?非常にループネストされた方法?

この問題に対する最も簡単なバイトコード操作ソリューションは何ですか?

4

5 に答える 5

11

この種のロジックを実行する標準的な方法は、必要な機能のインターフェイスを作成してから、その機能の 2 つ (またはそれ以上) の実装を作成することです。実装の 1 つだけがランタイムに読み込まれ、その実装は、if条件を完全に回避するために必要な仮定を行うことができます。

これには、各実装が相互に排他的であるという利点があり、JIT コンパイラーなどは、この特定の実行の役に立たないコードをすべて無視できます。

于 2013-10-24T19:19:23.927 に答える
7

最も簡単な解決策はここで機能します。自分のために物事を過度に複雑にしないでください。

final static booleanコンパイル時の定数 (JLS で定義されている)ではないaをどこかに配置し、「条件付き」コンパイルが必要な場所でそれを参照するだけです。JVM は最初にそれを確認したときにそれを評価し、コードが JIT されるまでに、JVM は値が変更されないことを認識し、チェックを削除し、値が の場合falseはブロックを削除できます。

いくつかの情報源: Oracle には、パフォーマンス テクニックに関する wiki ページがあり、可能な場合は定数を使用するように指示されています (このコンテキストでは、コンパイラは JVM/JIT であるためfinal、コンパイルでなくてもフィールドは定数としてカウントされることに注意してください)。 JLS規格による時定数)。そのページは、JIT が採用するパフォーマンス戦術のインデックスにリンクしています。このインデックスでは、デッド コードの削除を含む、定数の折りたたみやフローに依存した書き換えなどの手法について言及しています。

于 2013-10-24T19:20:37.743 に答える
0

JIT は、実行するたびにコードを再コンパイルします。知っているかどうかにかかわらず、あなたはすでにこれを行っています。これは、JIT が変更されていないと信じている (最終的である必要さえない) フィールドがある場合、そのフィールドはインライン化され、チェックとコードが最適化されて除去されることを意味します。

JITをスマートにしようとすることは、時間の経過とともに難しくなっています。

于 2013-10-24T21:13:35.830 に答える