ボクシングとアンボクシングとは何ですか?トレードオフは何ですか?質問する

ボクシングとアンボクシングとは何ですか?トレードオフは何ですか?質問する

明確で簡潔かつ正確な回答を求めています。

理想的には実際の回答ですが、良い説明へのリンクも歓迎します。

ベストアンサー1

囲まれた値はデータ構造最小限のラッパーであるプリミティブ型*. ボックス化された値は通常、ヒープ

したがって、ボックス化された値はより多くのメモリを使用し、アクセスするために少なくとも 2 回のメモリ検索が必要です。1 回はポインターを取得するため、もう 1 回はそのポインターをたどってプリミティブにアクセスするためのものです。明らかに、これは内部ループで必要な種類のものではありません。一方、ボックス化された値は通常、システム内の他の型とよりうまく連携します。これらは言語のファーストクラスのデータ構造であるため、他のデータ構造が持つと予想されるメタデータと構造を持ちます。

JavaとHaskellでは、ジェネリックコレクションはアンボックス化された値を含むことができません。.NETのジェネリックコレクションは、ペナルティなしでアンボックス化された値を保持できます。Javaのジェネリックはコンパイル時の型チェックにのみ使用されますが、.NETでは実行時にインスタンス化されるジェネリック型ごとに特定のクラスを生成する

Java と Haskell にはアンボックス配列がありますが、他のコレクションに比べると明らかに使い勝手が劣ります。ただし、最高のパフォーマンスが必要な場合は、ボックス化とアンボックス化のオーバーヘッドを回避するために多少の不便さを覚悟する価値はあります。

* この議論では、プリミティブ値とは、コールスタック、ヒープ上の値へのポインターとして保存されるのではなく、マシン型 (int、float など)、構造体、および場合によっては静的サイズの配列です。.NET の世界では、これらを値型 (参照型ではなく) と呼びます。Java の人々はこれらをプリミティブ型と呼びます。Haskellions では、これらを単に unboxed と呼びます。

** この回答では、私が知っている Java、Haskell、C# にも焦点を当てています。参考までに言うと、Python、Ruby、Javascript はすべてボックス化された値のみを持ちます。これは、「すべてがオブジェクト」アプローチ*** としても知られています。

*** 注意: 十分に高度なコンパイラ/JIT は、ソースを見たときに意味的にボックス化された値が、実行時に安全にボックス化されていない値になる可能性があることを実際に検出できる場合があります。本質的には、優れた言語実装者のおかげで、ボックスが自由になることがあります。

おすすめ記事