16バイトを超える構造体に最適なソリューション
-
03-07-2019 - |
質問
構造体として使用することを検討している型があります。
- 単一の値を表します
- 不変です
問題は、6つのintフィールドがあることです。
では、このタイプに使用するソリューションはどれですか?
- 構造体を使用しますか
- クラスに変更しますか
- または6つの整数をintの配列にパックします。したがって、フィールドは1つだけです
編集
6つの整数フィールドを持つ構造体のサイズは24バイトであり、これを渡すのは巨大です。 構造体の推奨サイズは16バイト以下です
解決
どのように使用するかによりますか?
- あなたはそれをたくさん割り当てるつもりですか?
- サードパーティのコードで消費されますか?この場合、通常、クラスを使用すると柔軟性が高まります。
- 構造体とクラスのセマンティクスが必要ですか?たとえば、null不可ですか?
- 特別なケースを表すために再利用できる、このクラスの事前に作成されたインスタンスがいくつかあると便利ですか? String.Emptyに似ています。この場合、クラスの恩恵を受けるでしょう。
質問で提供した情報だけで答えることは困難です。
他のヒント
ボクシングに注意してください。オブジェクトを予期するメソッドによって構造体が消費される場合、オブジェクトに強制され、パフォーマンスが低下する可能性があります。
こちらはリファレンスで詳細を説明しています。
クラス(#2)にすると、心配する必要がなくなります。
6つの整数の配列(#3)を使用すると、おそらくコードが読みにくくなります。各intの説明的な識別子を持つクラスの方がはるかに優れています。
構造体を見ずに、明確に何かを言うことは困難です。ただし、これは構造体のままにしておく必要があります。
WriteOnce<int[]>
はどうですか?
さまざまなオプションのパフォーマンスを測定するための小さなベンチマークを作成することをお勧めします。これが確実に知る唯一の方法です。結果に驚かれるかもしれません(私はしばしば)。
(ここでの懸念はパフォーマンスであると想定しています。)
データ所有者が不変になる場合、構造体対クラスの質問は、各インスタンスに存在する参照の平均数に依存する可能性が高いでしょう。 TwentyFourByteStruct [1000]の配列がある場合、すべての要素が異なる値を保持するか、すべての要素が同じ値を保持するか、中間にあるかに関係なく、その配列は24,000バイトかかります。 TwentyFourByteClass [1000]の配列がある場合、その配列は4,000または8,000バイト(32/64ビットシステムの場合)かかり、作成されるTwentyFourByteClassの個別のインスタンスは約48バイトかかります。すべての配列要素が同じTwentyFourByteClassオブジェクトへの参照を保持している場合、合計は4,048または8,048バイトになります。すべての配列要素が異なるTwentyFourByteClassオブジェクトへの参照を保持している場合、合計は52,000または56,000バイトになります。
実行時のパフォーマンスに関しては、一般に構造体を参照渡しすることで最高のパフォーマンスを得ることができます。構造体を値で渡すには、構造体をコピーする必要があります。16バイトを超える構造体にはコストがかかります(.netには16バイト以下の構造体の最適化が含まれます)が、参照による値型のコストは1バイトでも同じでも16,000バイト。
一般に、3つ以上の関連データを保存する場合、それらを結合するクラスを作成するのが好きです。特に、それらをユニットとして渡す場合。