11


2

Javaはどのようにして仮想関数の境界を越えてインライン化できますか?

私は、JavaがCよりも高速であるかどうかについてのいくつかの資料を読んでいて、次のような引用に遭遇しました。

_ JITは仮想関数の境界を越えてインライン化できるため、JavaはC ++よりも高速です。 _

http://www.jelovic.com/articles/why_java_is_slow.htm [Javaは常にCより遅くなる]](https://web.archive.org/web/20160906125304/http://www.jelovic.com/ articles / why_java_is_slow.htm [ウェイバックリンク])

これは何を意味するのでしょうか? Cはそのvtableを介して関数を呼び出す必要があるのに対し、JITは仮想関数呼び出しをインライン化できる(おそらくランタイム情報にアクセスできるため)ことを意味していますか?

3 Answer


10


あなたの質問に対する答えはイエスです。それが引用されたテキストの意味です。

JITはロードされたすべてのクラスを分析します。 ある時点で呼び出すことができるメソッドが1つしかないと判断できる場合は、ディスパッチを回避して(適切な場合は)メソッド本体をインライン化できます。

対照的に、Cコンパイラは可能なサブタイプのすべてを知っているわけではないため、この最適化が(仮想)メソッドに対して実行できるかどうかを判断することはできません。 (そしてリンカーが実行されるまでには遅すぎます…​)

他の答えはあなたがCでこの最適化を手で行うことができると言った …​ but that assumes that you (the programmer) can do the analysis 自分でメソッドを仮想から非仮想に変更します。 しかし、あなたがそれを誤解するならば、あなたは追跡するためのバグを持っています。

ところで、この最適化は平均的なJavaアプリケーションにとっては価値があると考えることができます。 もしそうでなければ、JITコンパイラはそれを実装していないでしょう。 結局のところ、価値のない最適化は、Javaアプリケーションの起動を遅くするためだけのものです。


4


Javaバイトコードのマシンコードへのコンパイルは実行時まで延期されるため、JVMが profile-guided最適化やその他の最適化を実行して情報が必要になるまでは実行可能コードは実行中です。 これには、以前に行われた最適化が取り消されて他の最適化が行われる可能性がある「最適化解除」も含まれる場合があります。

これに関する詳しい情報は、ウィキペディアの adaptive最適化にあります。これにはインライン化に関連する最適化が含まれています。


2


その価値のために、Java、C、Assemblyは比較的同じパフォーマンスを提供します。

はい、C、C、Asmのいずれかを最適化したほうがパフォーマンスが向上します。 …​ however, for the majorty of applications out there (try everything これはボトルネックではありません。そして、実装コストの低さが、パフォーマンスの低下を補います。