2009-08-20 6 views
3

4つの小数から成る約50万のデータポイントを処理する必要があります。私はこれを行うために構造体の配列を使用したいと思います。これは、配列の配列を使用するよりもはるかに遅いでしょうか?記憶は問題ではないようですが、スピードは速くなるでしょう - 速くする必要があります。二つのオプションの小規模な配列のアクセス時間と小さな構造体のアクセス時間#

クイックサンプルコード:

オプション1:

public struct Struct 
{ 
    public decimal A { get; set; } 
    public decimal B { get; set; } 
    public decimal C { get; set; } 
    public decimal D { get; set; } 
} 

使用:

private Struct[] data; 

オプション2:

private decimal [][] data; 

また、decimal正しいデータ型を使用しますか?データポイントはお金です...

ありがとう! ブライアン

+0

構造体で読み書き可能な自動プロパティを使用することをお勧めします。代わりにフィールドを公開することをお勧めします。クラス内の露出したフィールド上に露出した自動プロパティを優先させる理由はさまざまですが、構造に適用できるものはほとんどありません。コードが常にどのフィールドを使うべきかを知っているならば、露出フィールド構造体を使うことをお勧めします。さもなければ、良好な性能のための適切な代替案は、サイズ「N * 4」の「フラット」アレイに「N」個のアイテムを格納することであろう。 .netは1次元配列に最適化されているため、このようなアプローチでは高速なパフォーマンスが得られます。 – supercat

答えて

4

A、B、C、Dをまったく同時に処理する場合、構造体配列の配列は、データがまとまっているためメモリにページングされ、同じ時間(ページフォールトがより少ない)、CPUキャッシュに同時にフェッチされます。 Aのすべてを処理し、次にBなどのすべてを処理すると、その逆が真となり、配列の配列を使用する必要があります。

非常に難しくない場合は、両方のオプションを試して測定し、どちらが良いかを確認することをおすすめします。これが難しい場合は、より簡単でわかりやすいアプローチを使用し、パフォーマンス目標を達成するかどうかを判断してください。

+0

ありがとう - 私はすぐに感じているときに私は戻ってポストするテストの真っ只中に私は速かった。 –

+0

構造体の配列が急激に燃えていました。配列の配列を試してみると大変でした。構造体は、オブジェクトではなく軽量の値を渡しても、良いOODと可読性/保守性を引き続き維持できるという、両方の世界のベストを得ていると感じています。 すべての助けてくれてありがとう! –

1
  1. 通貨の値を扱っている場合、10進数は正しいタイプです。
  2. 構造体の配列は非常に高速です。

構造体の配列を扱うときは、個々のstruct要素(特にプロパティとして値を持つため)は、単一の不変オブジェクトとして扱う必要があることに注意してください。この一部を減らすことができ、公共分野への切り替え

MyStruct val = array[5]; 
val.C = newValue; 
array[5] = val; 

を、それ自身の問題を追加します。これは、配列要素4にCを変更したい場合は、あなたがする必要があります、ということを意味します。変更可能な構造体は時々複雑になります...

1

あなたは2次元配列で配列の配列を交換する場合うーん...、結果としてメモリレイアウトは、多かれ少なかれ同等でなければなりません:

private Struct[] data = new Struct[x]; 
private decimal[,] data = new decimal[x,4]; 

あなたはのいずれかの周りを通過するために期待していた場合を除き他の方法との配列...

2

2次元配列の使用に関する以前の記事にジャスト側のコメント:

配列の配列は、(時にはジャグ配列と呼ばれる)ため、2次元配列よりも優れた性能を提供します2次元アドレスtr anslationには乗算と加算が必要ですが、ギザギザの配列には2つの加算が必要です。

もちろん、違いは数百万回のルックアップ後にのみ表示されます。

+1

倍数があることは事実ですが、実際のパフォーマンスの向上は、1次元配列アクセスのための専用のIL命令があり、2次元配列ではないためです(http://blogs.msdn.com/ericlippert/archive/2009 /08/17/arrays-of-arrays.aspx)。 – bmm6o

+0

これは少し混乱していますが、私は間違っているかもしれませんが、パフォーマンスの向上は逆参照にあると思います... "ジグザグ"配列を使用すると、2つの追加、逆参照、および別の追加が行われます。私は間違っているかもしれませんが、私はかなり遅くなってしまうだろうと確信しています...私はより多くの情報には開いていますが、私はいつも2次元配列がより速くなると思っていました – LorenVS

1

お金を扱う場合、比較や単純な加算や減算を行い、丸め誤差を心配する必要がない場合は、整数を使用する方が高速で効率的です。

+0

しかし、 1つのフィールドでドルを表し、別のフィールドでセントを整数として表現し、プログラム上持ち越しを実行することをお勧めしますか? –

+0

セントを使用するか、精度が必要なものを使用します。あなたの場合は小数点以下4桁ですので、ユニットとして1/100セントを使用します。だから$ 12.3456は123456として表されます。あなたが通貨について心配する必要がある唯一の時間は、数字をフォーマットするときです。あなたが大量に対処するなら、長い整数を使うことができます。 – sylvanaar

1

構造体配列とジグザグ配列は、メモリとほぼ同じ方法でレイアウトされているため、使用するとパフォーマンスが低下することはありません。

public struct Struct 
{ 
    // Unless you're filling your get/set blocks with anything, 
    // these properties will be in-lined in compilation time 
    // and will have the same performance/behavior as using public fields 

    public decimal A { get; set; } 
    public decimal B { get; set; } 
    public decimal C { get; set; } 
    public decimal D { get; set; } 
} 

だから、私は公共のフィールドを使うことを考えます。しかし、それは私の意見です。私は物事がどのように行動するかを明示的に知りたいのです。

お金のための小数点の使用については、必ずしもそうではありません。 10進数は128ビットのデータフィールドですが、非常に高精度ですが、整数部分は狭い範囲の値を持ちます。あなたがこのような料金を計算するために高精度を必要とするが、あなたは本当に高い値を必要としない場合は、小数点に行く。より高い値を必要とし、あまり正確ではない場合は、2倍にしてください。小さな値を扱っていて、かなりの精度が必要な場合は、浮動小数点のために行ってください。

データ型が32ビット(またはバスの幅)に近いほど、データのロードに要する時間が短くなることに注意してください。

希望すると便利です。

関連する問題