連載
プロフェッショナルVB.NETプログラミング
第3回 構造体の宣言とその効能
(株)ピーデー
川俣 晶
2002/04/16
|
|
構造体の効能
構造体はクラスとほぼ同じ機能を持つ。では、どうしてクラスで代用することはできず、構造体という独立した機能が存在するのだろうか? また、クラスと構造体は何が異なり、どう使い分けるべきなのだろうか? 構造体とクラスの決定的な違いを示すサンプル・ソースを以下に示す。これは、C#入門「第5回 C#のデータ型」に掲載した構造体とクラスの比較のサンプル・ソースをVB.NET用に書き換えたものである。まず、クラスを用いた例から。
1: Public Class Form1
2: Inherits System.Windows.Forms.Form
3:
4: #Region " Windows フォーム デザイナで生成されたコード "
5:
6: Public Class Test
7: Public v As Integer
8: End Class
9:
10: Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
11: Trace.WriteLine(DateTime.Now)
12: Dim count As Integer
13: count = 10000000
14: Dim test(count) As Test
15: Dim i As Integer
16: For i = 0 To count - 1
17: test(i) = New Test()
18: test(i).v = i
19: Next
20: Dim sum As Long
21: For i = 0 To count - 1
22: sum = sum + test(i).v
23: Next
24: Trace.WriteLine(DateTime.Now)
25: End Sub
26: End Class |
|
クラスを用いた場合の実行性能を調べるVB.NETのサンプル・プログラム8 |
これを実行すると以下のようになる。
2002/03/31 13:29:48
2002/03/31 13:29:55
|
|
サンプル・プログラム8の実行結果 |
実行した環境は、Pentium 4/1.5GHz、メモリ512Mbytesのマシンである。約7秒でこれを処理したことになる。これがメモリ256Mbytesのマシンになると、激しくハードディスクにスワップが発生する。メモリ消費量も大きいサンプル・プログラムである。
では、このサンプル・ソースの6行目のClassキーワードをStructureキーワードに変更してみよう。
1: Public Class Form1
2: Inherits System.Windows.Forms.Form
3:
4: #Region " Windows フォーム デザイナで生成されたコード "
5:
6: Public Structure Test
7: Public v As Integer
8: End Structure
9:
10: Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
11: Trace.WriteLine(DateTime.Now)
12: Dim count As Integer
13: count = 10000000
14: Dim test(count) As Test
15: Dim i As Integer
16: For i = 0 To count - 1
17: test(i) = New Test()
18: test(i).v = i
19: Next
20: Dim sum As Long
21: For i = 0 To count - 1
22: sum = sum + test(i).v
23: Next
24: Trace.WriteLine(DateTime.Now)
25: End Sub
26: End Class |
|
クラスの代わりに構造体を用いたVB.NETのサンプル・プログラム9 |
これを実行すると以下のようになる。
2002/03/31 13:30:14
2002/03/31 13:30:15
|
|
サンプル・プログラム9の実行結果 |
見ての通り1秒もかかっていない。またメモリ256Mbytesのマシンで実行しても、スワップは発生しない。つまりメモリ消費量も小さい。さらに、17行目は実は不要であり、これを取り除けばもっと速くなる。これは、たった1カ所のキーワードがClassかStructureかの相違で発生した大きな差である。つまり、機能は似ているとしても、クラスと構造体を適切に使い分けることは性能に大きく影響するわけである。
技術的に見ると、クラスと構造体の差は、それが参照型であるか値型であるかの違いである。参照型とは、情報が独立したメモリ領域に確保され、そのメモリ領域の場所を指し示す参照情報を経由して参照されるデータ型である。これに対し値型とは、情報を保存するメモリ領域が、直接、値型を含むメモリ内に確保される方法を示す。つまり、上記の例であれば、クラス使用時はTestクラスのインスタンスとなる10000000個の小さなメモリ領域と、それを参照するためのアドレスを含む配列が確保されたのに対して、構造体の場合は構造体の内容そのものが配列の中に確保されるので、実際には1個の大きなメモリ領域を確保している。メモリ確保という処理が、1回で済むか、10000001回繰り返すかが、大きな性能差を生んでいるわけである。
しかし構造体の利用が常にクラス利用より速いわけではない。大きな情報の受け渡しの場合、クラスを使用すると、単にデータの場所を伝えるだけで済み、極めて迅速である。それに対して、構造体を用いた場合は、構造体の内容をすべてコピーすることになるので、処理が遅くなる。一般的に、サイズの大きいデータを頻繁に受け渡す場合は、クラスを用いた方が処理速度は速くなる。
このように、構造体とクラスは、目的や状況に応じて使い分けが必要とされる。なお、クラスに関する話題は後でまた詳しく取り上げる。
まとめ
今回は行番号使用時の注意点、固定長文字列の扱い、そして構造体とクラスについて取り上げた。クラスに関する詳細は次回以降で詳しく解説するつもりだが、それぞれを使い分けるポイントはご理解いただけただろうか。
次回は、今回少し触れたVBFixedString属性の活用方法や、VB 6とVB.NETでの変数のスコープの違い、文字列を扱う関数における相違点について取り上げるつもりだ。
では次回もまた会おう。
Insider.NET 記事ランキング
本日
月間