何らかのインターフェース I を実装するクラス A があるとします。
I i = new A();
i.method(); // example 1
A a = (A)i;
a.method() // example 2
「method()」への呼び出しごとに生成される IL コードは同じですが、メソッド「method()」への呼び出しのどれがネイティブ コードでよりコストがかかり、その理由は?
どんな助けでも大歓迎です。
何らかのインターフェース I を実装するクラス A があるとします。
I i = new A();
i.method(); // example 1
A a = (A)i;
a.method() // example 2
「method()」への呼び出しごとに生成される IL コードは同じですが、メソッド「method()」への呼び出しのどれがネイティブ コードでよりコストがかかり、その理由は?
どんな助けでも大歓迎です。
IL コードが同じ場合、ネイティブ コード (のコスト) も同じです。なぜJITはそれらを異なる方法で扱うのでしょうか?
一般に、((A)a).method()
JIT コンパイラーは呼び出す必要がある具体的なメソッドを (静的に) 認識しており、A.method
直接呼び出すことができるため、 への呼び出しは (ごくわずかに) 高速になります。インターフェイスを介して呼び出すにはI
、参照が指しているオブジェクトの実際のタイプを実行時にチェックしてから、その実装にディスパッチする必要があります。ただし、そのための参照はありません。
すべてのメソッド呼び出しが仮想であるため、Java JIT コンパイラーがこの点でいくつかの最適化を行っていることは知っています。特定のインターフェイス メソッドの最も使用されている実装を推測してキャッシュし、その場合に最適化します。メソッドは明示的に仮想化する必要があるため、.NET JIT ではこれはほとんど必要ありません。
これはまさにマイクロ最適化のケースであり、実際に心配する必要はありません。