C/C++ の最適化はコンパイル時に生成され、Java の最適化は実行時に生成されるという事実について。Java プログラムを C で (最適化された) 同じプログラムよりも高速に取得することは可能ですか?
ランタイムの最適化はコンパイル時間よりも優れている可能性があることを理解しています。したがって、これらの最適化の利点を JVM の実行のオーバーヘッドと比較できるかどうか疑問に思っています。
C/C++ の最適化はコンパイル時に生成され、Java の最適化は実行時に生成されるという事実について。Java プログラムを C で (最適化された) 同じプログラムよりも高速に取得することは可能ですか?
ランタイムの最適化はコンパイル時間よりも優れている可能性があることを理解しています。したがって、これらの最適化の利点を JVM の実行のオーバーヘッドと比較できるかどうか疑問に思っています。
理論的には、そうです。実際には、その可能性は非常に低いです。
基本的な仮定の 1 つは、C/C++ はバイナリ オペコード ターゲット用に 1 回コンパイルされ、Java はそれが実行されている特定のマシン用にコンパイルされるというものです。これにより、Java が優位に立つはずです。しかし現実には、C/C++ でさえ、実行時に動的に選択される複数の最適化パスを持ち、特定のターゲットのコンパイルの利点を最大限に活用できます。
逆に、Rekin が述べているように、Java JVM は Java プログラムを動的にプロファイリングして、何をどのように最適化するかを知る必要があります。プロファイリングはそれ自体が高価な操作であり、そのオーバーヘッドを Java JVM から取り除くことはできません。一方、現在のワークロードに適した最適化セットを選択すると、優位性が得られます。実際には、ほとんどの C プログラム (すべてではありませんが :) はタスクに合わせて適切に調整されており、プロファイリング手法を使用して最適化する必要はほとんどありません。
Java には、これらのコンパイルの問題を完全に小さくする効果が他にもあります。おそらく最初の位置はガベージコレクターです。
ガベージ コレクターの最初の使命は、プログラミングを容易にし、C/C++ の最も厄介な再発バグの 1 つであるメモリ リークに対処し、回避することです。この機能だけでも、多くの産業環境で Java を大量に使用することが正当化されます。
ただし、コストがかかります。非常に大きなもの。調査によると、ガベージ コレクターが最小限のオーバーヘッドで動作するようにするには、厳密に必要なメモリ量の約 5 倍のメモリが必要です。そのため、このような量のメモリが不足すると、GC オーバーヘッドが大きくなり始め、パフォーマンスが低下します。
逆に、状況によっては、アルゴリズムのメモリ割り当て料金を解放することで、アルゴリズムを変更し、より優れた高速なアルゴリズムを採用できる場合があります。このような状況では、Java が優位に立つことができ、C プログラムよりも高速になります。
しかし、ご想像のとおり、これは珍しいことです...
JVM のオーバーヘッドは膨大です。zip (jar) ファイル内に存在し、抽出する必要があるいくつかのクラスをロードする必要があります。
ロードされたすべてのクラスに対して、いくつかの静的分析メソッドが実行され、到達不能なコード、オペランド スタック タイプの問題などがあるかどうかが確認されます。
次に、コードのどの部分を最適化する価値があるかを判断するために、常にプロファイラーが実行されます。これは通常、これらのメソッドを最適化する前に数千回呼び出す必要があることを意味します。
それに加えて、ガベージ コレクターも取得します。
適切に作成された C プログラムが、実行中のプラットフォーム用にコンパイルされ、同等の Java よりもパフォーマンスが優れているとは、私には本当に想像できません。おそらく、JVM には何らかの最適化があり、C コンパイラにはその特定の最適化が実装されていないというまれなケースに遭遇した場合に限ります。