DOBON.NET DOBON.NETプログラミング掲示板過去ログ

構造体配列のパフォーマンスについて

環境/言語:[2002(.NET Framework 1.0)]
分類:[.NET]

こんにちは。
VB6からの移行で比較的単純な構造体を配列で保持するようなコードを作っているのですが、
件数的には1万件ほどでテストした結果、速度的に以下のような結果になりました。
(コードはより簡単にしたサンプルです)
ボックス化とかが影響している?かとか詳細なことはわかりませんが、一般的にはどのよう
に作成するのがもっとも効率がよい方法でしょうか?
構造体のメンバーがこういうケースならとかケースによる場合などもあればご教示頂けると
有難いです。よろしくお願いします。

1 宣言1-(1) 
2 宣言2-(1) 
3 宣言2-(2) 
4 宣言1-(2) 

宣言1

    Private Structure Seito
        Public Simei As String  
        Public tensu As Integer  
    End Structure

宣言2

    Private Class Seito
        Public Simei As String  
        Public tensu As Integer  
    End Class

(1)
    Private Gakkyu As Seito()

    ReDim Preserve Gakkyu(0)

    Gakkyu(0) = New Seito()

    Gakkyu(0).Simei = "ビル ゲイ太"
    Gakkyu(0).tensu = 50
    

(2)
    Private Gakkyu As New ArrayList()

    Dim iSeito As Seito = New Seito()

    iSeito.Simei = "ビル ゲイ太"
    iSeito.tensu = 50

    Gakkyu.Add(iSeito)
> 件数的には1万件ほどでテストした結果、速度的に以下のような結果になりました。

結果の記載が無いようです。

> ボックス化とかが影響している?かとか詳細なことはわかりませんが、一般的にはどのよう
> に作成するのがもっとも効率がよい方法でしょうか?

「構造体を使用する理由」が無いなら、クラスにしてしまった方が総合的には有利なはずです。

また、配列よりもコレクションを使った方がよいと思います。
ありがとうございます。

> 結果の記載が無いようです。

紛らわしい書き方ですいません。この部分が宣言と処理の組み合わせの結果の順位になります。上から速度が速かった順です。

> 1 宣言1-(1) 
> 2 宣言2-(1) 
> 3 宣言2-(2) 
> 4 宣言1-(2) 

>「構造体を使用する理由」が無いなら、

理由と言いますか、一般的に小さなデータを頻繁に扱う場合はStructureのほうが処理が早いと入門書で読んだ記憶があったためです。
(ボックス化にまで突っ込んだ記載はありませんでした。)

> また、配列よりもコレクションを使った方がよいと思います。

これはCollectionBaseを継承した独自のコレクションを定義するということででしょうか?
これからそちらの方のサンプルも作ってみます。
お世話になります。下記のように独自のコレクションクラスを作成してテストしてみまし
たが、ArrayList使用時と変わらないようです。なんか.NETは同じ機能を実装するのに色々
な書き方ができるので、混乱ぎみです。すべてオブジェクト指向で書くのが本来なのでしょ
うが、速度等との兼ね合いがあるので、今回は構造体(Structure) + 配列でいきたいと思
います。 

Public Class MyCollection
    Inherits CollectionBase

    Public Shadows Function Add(ByVal Obj As Object) As Object
        MyBase.List.Add(Obj)
        Return Obj
    End Function

    Public Shadows Sub Remove(ByVal Obj As Object)
        MyBase.List.Remove(Obj)
    End Sub
End Class

Private Gakkyu As New MyCollection()

#関係ありませんが、アイコンはこあらを選んでるのですが、これはねずみなような・・?
解決済み!
> お世話になります。下記のように独自のコレクションクラスを作成してテストしてみましたが、ArrayList使用時と変わらないようです。
CollectionBase を使う限り結局はボクシング/アンボクシングが発生するので、構造体のコレクションには好ましくないでしょうね。
パフォーマンスが厳しいなら IList/ICollection を自前で実装することになるでしょうか。内部で配列を持って。
.NET 2.0 であれば List<T> で解決するんですが。

> すべてオブジェクト指向で書くのが本来なのでしょうが、速度等との兼ね合いがあるので、今回は構造体(Structure) + 配列でいきたいと思います。
ご安心ください、.NET では構造体も配列もオブジェクトです。

あと、
> 一般的に小さなデータを頻繁に扱う場合はStructureのほうが処理が早い
どういうものを構造体にするべきかは、MSDN のガイドラインにも書かれています。
一度目を通すべきでしょう。
なお、C#/VB では構造体と言う言葉を使いますが、どちらかというと「値型」と言う方が実情に即します(実際、C++/CLI などでは参照型の構造体なんてのも存在します)。
解決済み!
Hongliangさん、ご丁寧な説明ありがとうございます。
一旦解決済みにしたのですが、説明を読んで参照型と値型でちょっと気になったことがありましたので、外しました。
例えば構造体の定義がClassとStructureでは下記のように書いた場合、動作が違ってきます。
構造体がClassの場合、新しいインスタンスを作成しないと後の代入で値が全て置き換わってしまいます。

Seito.tensu = 50
Gakkyu.Add(Seito)

Seito.tensu = 100
Gakkyu.Add(Seito)

参照型なので当たり前と言われればそれまでなのですが、構造体がClassなのかStructureなのか不明なケースや今まで
のVB6のType型と同じように使おうとするケースなどないのかと思いまして・・・・
ユーザー定義の構造体をClassで定義する場合、普通どのようにこの辺りをクリアするのが普通でしょうか?
(VB6とは考えを変えるとか、直接構造体を触らせないなど)
初歩的なことですいませんが、よろしくお願いします。
構造体は structure の翻訳なので、class の構造体と言うのはちょっと。

> ClassなのかStructureなのか不明なケース
ドキュメントを作れと言うのが Microsoft の方針です。
// 確かにもうちょっと区別できる仕組みがあっても良かったとは思います。

> ユーザー定義の構造体をClassで定義する場合、普通どのようにこの辺りをクリアするのが普通でしょうか?
VB6 の考えというのがどんなのか知りませんが、とりあえず Microsoft は構造体を使用すべき状況をガイドライン(『クラスまたは構造体の選択』)で示しています。
基本的に値型ってのはごく単純で小さくてまさに値であるものについてだけ使用しろ、ってことですが。
クローンを作りたい場合は、ICloneable インターフェイスを実装させることが多いです。
>>また、配列よりもコレクションを使った方がよいと思います。
>
> これはCollectionBaseを継承した独自のコレクションを定義するということででしょうか?

いいえ。

System.Collection.Generics 配下の List や Dictionary 辺りを使いましょうという話です。

DOBON.NET | プログラミング道 | プログラミング掲示板