ボクシングとアンボクシングのパフォーマンスは同じですか?またはunboxingが速いとしましょう。ボクシングとアンボクシングのパフォーマンスは同じですか?
(そうならば、あなたは簡単に主な理由を説明することができます。)
おかげ
ボクシングとアンボクシングのパフォーマンスは同じですか?またはunboxingが速いとしましょう。ボクシングとアンボクシングのパフォーマンスは同じですか?
(そうならば、あなたは簡単に主な理由を説明することができます。)
おかげ
それは、部分的に使用すると、「ボックス化解除」によって何を意味するかによって決まります。 ILの言葉では、アンボクシングは実際にはC#よりもやや少なくなります。 Cでは、 "unboxing"はいつもの値をにコピーしますが、ILではボックスのタイプをチェックして値を利用できるようにすることだけを意味します。そうです。
ボクシングには新しいオブジェクトの割り当てが必要ですが、タイプチェックは必要ありません。
ILレベルでアンボックスするのは、実際にアンボックスしようとしているオブジェクトが実際に同じタイプ(または互換性のあるもの)のボックス化された値であることを確認するだけです。次に、unboxingのC#版で値のコピー操作を追加する必要があります。
私は割り当てが唯一のアップフロントの割り当てのコストが、その後ヒットに対応するガベージコレクションが存在しないため、特に、型チェックよりも、長期的にはより高価であることを期待します。
いつものように、実際のコードのコンテキストで操作のパフォーマンスコストを評価する必要があります。私はジェネリックスが収集などのためにそれらを避けることができるほとんどの現代の.NETアプリケーションでボクシングとunboxingのコストが重要であるとは期待していません
最終的に1つまたは複数の機械語の形式の任意の値型は、読み込み時に常にコピーされなければならないという事実を指摘する価値があります。 IL命令「isinst」は、前記値のコピーを実行しなければならず、同様にコンパイルされたC#コードもコピーしなければならない。ステートメントの「値をスタック上で利用できるようにする」というのはもちろん、操作のセマンティクスを説明するときに当てはまりますが、「無料で入手する」とは簡単に解釈できます。 –
私の知る限り、unboxingはボクシングよりもはるかに安いです。これを考慮してください:
Int32 v1 = 5;
v1
がスタックに割り当てられます。
Object r = v1; // boxing
コンパイラはv1
の値をとり、それに基づいてオブジェクトを作成します。それには(いくつかの理由から)時間がかかります。このコードが実行されるが
:
Int32 v2 = r; //unboxing
れる何が起こるか、そのコンパイラはv2
にそれをr
自体に箱詰めした後、コピーの値へのポインタを取得します。
ガベージコレクション環境でのボクシングとアンボクシングのパフォーマンスを決定する基本的な要因がいくつかあります。
x64マシンで64ビット整数(C#の場合はlong
など)を使用しているとします。さらに、トレースガベージコレクションを使用してスタックベースの仮想マシン内で行われるものとします。
まず、ある場所から別の場所に任意の量のメモリを移動するコストがあります。ランタイムは、ボックス化された整数の実際の値をスタックにコピーする必要があります。これにより、便利なことができます。同様に、逆の場合、スタックからヒープ(参照型が格納される)に値をコピーする必要があります。これは、ハードウェアのサブシステムの多くに触れるかなり複雑な操作です。我々が懸念している限り、この要素は固定コストとみなされ、両方の操作で同じです。
第2に、ボクシングのケースでは、ヒープに参照型を割り当てる必要がありますが、これは値を保持します。これには、スペアメモリの配置、適切なオブジェクトヘッダーのメモリへの書き込み、整数そのものの値のような適切なハウスキーピングが必要です。
第3に、アンボックスのケースでは、実行時に型チェックを実行して、アンボクシング操作が実際に正しいかどうかを判断し、正しい結果を生成する必要があります。場合によっては、ボックス化されないオブジェクトの型を静的に推論することは可能かもしれませんが、これは実行している操作に直接関係するのではなく、コンパイラの最適化(または型システムの機能)です。
第4に、ボックス化された整数の隠れた長期的なコストは、他の参照型と同様に、ガベージコレクションに参加する必要があるということです。これは、それへの参照が記録される必要があるかもしれないことを意味し、生存性を決定するために追跡されなければならず、潜在的に異なる世代にコピーする必要がある。もちろんこれはすべての参照タイプに当てはまりますが、このレベルでのパフォーマンスについて考えているかどうかは、考慮する必要があります。
要するに、コストは、コンパイラ、ランタイム、および実行中のハードウェアのバージョン固有の動作の数によって異なります。したがって、簡単な答えを出すことは容易ではありません。
私は難しい事実はありませんが、私はunboxingが少し速くなることを期待しています。値の種類を入力すると、新しいオブジェクトを作成し、その値を新しいオブジェクトにコピーする必要があります。ボックス化を解除するときは、ボックス化されたインスタンスから値のみをコピーする必要があります。だからボクシングは、オブジェクトの作成を追加します。しかし、これは.NETでは非常に速いため、違いはあまりないでしょう。最大のスピードが必要な場合は、最初の場所でボクシングの手順全体を避けてください。ボクシングは、ガベージコレクタによってクリーンアップされる必要があるオブジェクトを作成することを忘れないでください。 –
実際の答えを書くのにもっと具体的な知識を持つ人が待っていますが、unboxingはメモリ割り当てを伴わないので、ガベージコレクタのためにすぐにまたは長期にわたってオーバーヘッドがかなり少なくなります。 –
(続き):最後に(より一般的なヒントとして):厳しい事実が必要な場合は、特定のユースケースについて常に独自の測定を行います。実際のホットスポットを特定し、時期尚早に最適化しようとしないでください。 –