値型と参照型、ボックス化とボックス化解除 [C#]

基本的なことを今一度確認する。

値型(スタック)

  • 基本の組み込みデータ型
  • ユーザー定義の構造体を使用して変数が宣言されている場合
例:
int x = 10;

スタックの使用は効率的ですが、値型の有効期間は限られているため、複数のクラス間におけるデータ共有には適していません。


参照型(ヒープ)

  • クラス インスタンスや配列など
  • string データ型

例:
int[] num = new int[10]; // int型 10の配列

ガベージ コレクションが不要であると判断した時点でクリアされます。
参照型の宣言ではオーバーヘッドが大きくなりますが、他のクラスからアクセスできるという利点があります。




ボックス化とボックス化解除

ボックス化とは、値型を参照型に変換する処理をいいます。
つまり、ヒープ → スタック

例:boxing
int i = 123;
object o = (object)i;  // boxing
object o = i;  // Implicit boxing
string s = i.ToString(); // boxing


例:unboxing
object o = 123;
int i = (int)o;  // unboxing

ArrayList list = ArrayList();
int n = 123;  // n is a value type
list.Add(n); // n is boxing
n = (int)list[0]; // list[0] is unboxing


引用:値型と参照型 (Visual C# Express)より
簡単な代入と比べて、ボックス化およびボックス化解除は負荷の大きいプロセスです。値型をボックス化するときは、新しいオブジェクトを割り当てて構築する必要があります。ボックス化ほどではありませんが、ボックス化解除に必要なキャストも大きな負荷がかかります。


パフォーマンス
引用:パフォーマンス (C# プログラミング ガイド)より
System.Collections.ArrayList などの非ジェネリック コレクション クラスで、頻繁に値型をボックス化する必要がある状況では、値型の使用を回避するのが最も適しています。System.Collections.Generic.List<(Of <(T>)>) などのジェネリックコレクションを使用することで、値型のボックス化を回避できます。ボックス化とボックス化解除は、負荷の大きい処理です。値型をボックス化するときは、完全に新しいオブジェクトを作成する必要があります。これには、単純な参照割り当てと比較して最大 20 倍もの時間がかかることがあります。また、ボックス化を解除するときは、キャストのプロセスで代入の 4 倍の時間がかかることがあります。



参考:

0 Comments:

Sony Style(ソニースタイル)
デル株式会社

Recent Posts