1

switch最近、静的コード分析ツール (PMD) が、分岐が少なすぎるステートメントについて不平を言う状況に遭遇しました。すぐにもっと多くのケースが追加されることを知っていたので、私はやりたくありませんでした。しかし、javacがそのような最適化を実行するかどうかは疑問でした。JAD を使用してコードを逆コンパイルしましたが、それでもスイッチが表示されました。これは JIT によって最適化されたランタイムである可能性はありますか?

更新:私の質問の文脈に惑わされないでください。私はPMDについて尋ねているのではなく、マイクロ最適化の必要性についても尋ねていません。質問は明らかにこれだけです:現在の(Oracle 1.6.x) JVM実装には、スイッチも処理するJITが含まれていますか?いくつかの枝かどうか。

4

4 に答える 4

2

JIT コンパイラーが switch ステートメントを最適化する方法を判別する方法は、次のいずれかです。

  • JIT コンパイラのソース コードを読む (OpenJDK 6 および 7 はオープン ソースです)、または
  • 対象のクラスの JIT コンパイル済みコードをファイルにダンプするように指示するスイッチを指定して JVM を実行します。

パフォーマンスと最適化に関連するすべての質問と同様に、答えはハードウェア プラットフォームと JVM のベンダーとバージョンによって異なります。

参考:Java JITコンパイル済みネイティブバイトコードの逆アセンブル


この質問が「単なる怠惰な好奇心」である場合は、それで構いません。

switchただし、使用するため、またはifパフォーマンス上の理由からコードを書き直すことは、おそらく悪い考えであり、時間の無駄であることも指摘しておく必要があります。

  • 元のバージョンと手動で最適化されたバージョンの間の時間の差 (あるとしても) は取るに足らない可能性があるため、これはおそらく時間の無駄です。

  • 最適化は特定のハードウェアと JVM の組み合わせにのみ役立つ可能性があるため、これは悪い考えです。他の人には、効果がないかもしれません...またはアンチ最適化でさえあるかもしれません。

つまり、JIT オプティマイザーがこれをどのように処理するかを知っていたとしても、おそらくプログラミングでそれを考慮すべきではありません。

(もちろん、実際に測定可能なパフォーマンスの問題があり、プロファイリングが (たとえば) 3 つのブランチをボトルネックの 1 つとして指摘している場合は例外ですswitch。)

于 2012-09-12T11:54:57.370 に答える
1

デバッグモードでコンパイルした場合、逆コンパイルしてもスイッチが表示されるのが普通です。そうしないと、デバッグを試みると、行番号や元の命令フローなどの情報が失われます。
したがって、本番モードでコンパイルして、逆コンパイルの結果がどうなるかを確認できます。

ただし、switchステートメントは、特に成長が予想される場合は、一般にコードの臭いと見なされ、リファクタリングの適切な候補として評価する必要があります。

于 2012-09-12T11:34:41.677 に答える
1

質問が何であるかについてのあなたの明確化の後に関しては。

これはハードウェアと JVM に強く依存するため (Java 商標を使用する JVM は、JVM 仕様に準拠している限り、Oracle 以外の企業によって開発される場合もあります) 唯一の有効な方法は、速度テストを行うことです。

コードのチャンクを切り取り、かなりの量の繰り返しのためにループにロックし、ループの実行前後の時間を確認します。両方のソリューションに対して繰り返します (switch と if)

これは単純でばかげているように見えるかもしれませんが、実際には機能し、逆コンパイル、バイトコードやメモリ ダンプの読み取りなどよりもはるかに高速です。


Java は実際に仮想マシンとバイトコードを使用することを覚えておく必要があります。これはすべて処理され、最適化されていると確信しています。高水準言語を使用して、あなたが求めているようなマイクロマネジメントや最適化を回避しています

より一般的に言えば、最適化が少し早すぎると思います。そのスイッチでさらに多くのケースが発生することがわかっている場合、わざわざ気にする必要はありません。プロファイラーを実行しましたか?そうでない場合は、最適化しても意味がありません。「時期尚早の最適化は諸悪の根源です」. 実際にはボトルネックではないコードの一部を最適化し、コードの複雑さを増し、まったく貢献しないコードを書くことに自分の時間を浪費している可能性があります。

あなたが作成しているアプリの種類はわかりませんが、経験則では明快さが王様であり、通常はよりシンプルでエレガントな自己文書化ソリューションを選択する必要があります.

于 2012-09-12T11:41:33.607 に答える
0

javac のパフォーマンスはほとんど最適化されていません。すべての最適化は、JIT を使用して実行時に実行されます。パフォーマンスに問題があることを知っていない限り、そうではないと思います。

PMDが不平を言っているのは、明確さです。例えば

if (a == 5) {
  // something
} else {
  // something else
}

よりも明確です

switch(a) {
   case 5:
       // something
       break;
   default:
       // something else
       break;
}
于 2012-09-12T11:31:23.320 に答える