基本的なことを今一度確認する。
値型(スタック)
- 基本の組み込みデータ型
- ユーザー定義の構造体を使用して変数が宣言されている場合
例: 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:
コメントを投稿