Javaの合理的な実装の場合:
各オブジェクトは、とりわけ含むヘッダを有し、実行時の型へのポインタ(例えば、Double
又はString
、それはすることができませんでしたCharSequence
又はAbstractList
)。ランタイムコンパイラ(通常、Sunの場合はHotSpot)がタイプを静的に決定できないと仮定すると、生成されたマシンコードでいくつかのチェックを実行する必要があります。
最初に、ランタイムタイプへのポインタを読み取る必要があります。いずれにしても、同様の状況で仮想メソッドを呼び出すために必要です。
クラス型にキャストする場合、を押すまでスーパークラスがいくつあるかが正確にわかるjava.lang.Object
ため、型ポインターから一定のオフセットで型を読み取ることができます(実際にはHotSpotの最初の8つ)。これも、仮想メソッドのメソッドポインターを読み取ることに似ています。
次に、読み取られた値は、キャストの予想される静的タイプとの比較が必要です。命令セットのアーキテクチャによっては、別の命令が誤った分岐で分岐(またはフォールト)する必要があります。32ビットARMなどのISAには条件付き命令があり、悲しいパスをハッピーパスを通過させることができる場合があります。
インターフェイスの多重継承により、インターフェイスはより困難になります。通常、インターフェースへの最後の2つのキャストは、ランタイムタイプにキャッシュされます。非常に早い段階(10年以上前)では、インターフェースは少し遅くなりましたが、それはもはや関係ありません。
うまくいけば、この種のことはパフォーマンスにほとんど関係がないことがわかります。あなたのソースコードはより重要です。パフォーマンスの点では、シナリオの最大のヒットは、オブジェクトポインターをいたるところに追跡することによるキャッシュミスである可能性があります(型情報はもちろん一般的です)。