質問

非常に小さなオブジェクトが必要な場合、たとえば2つのfloatプロパティが含まれている場合、「破棄」されない数百万のオブジェクトがあります。すぐに、構造体はより良い選択またはクラスですか?

ライブラリとしてのxnaのように、構造体としてpoint3などがありますが、それらの値を長期間保持する必要がある場合、パフォーマンスの脅威になりますか?

役に立ちましたか?

解決

構造体に関するほとんどの質問とは異なり、これは実際には構造体の適切な使用方法のようです。含まれるデータが値型であり、これらの多くを使用する場合、構造はうまく機能します。

ヒント:

::構造体は16バイトを超えてはなりません。そうしないと、パフォーマンス上の利点が失われます。

::構造体を不変にします。これにより、使用法が明確になります。

例:

public struct Point3D {

   public float X { get; private set; }
   public float Y { get; private set; }
   public float Z { get; private set; }

   public Point3D(float x, float y, float z) {
      X = x;
      Y = y;
      Z = z;
   }

   public Point3D Invert() {
      return new Point3D(-X, -Y, -Z);
   }

}

他のヒント

答えは、オブジェクト/値が最終的に保存される場所によって異なります。 ArrayListのような型付けされていないコレクションに保存する場合、それらをボックス化することになります。ボクシングは、構造体のオブジェクトラッパーを作成し、フットプリントはクラスオブジェクトと同じです。一方、T []やListなどの型付き配列を使用する場合、構造体を使用すると、各要素の実際のデータのみが格納され、要素全体ではなくコレクション全体のフットプリントのみが格納されます。

したがって、構造体はT []配列での使用により効率的です。

大きな懸念事項は、メモリがスタックまたはヒープのどちらに割り当てられているかです。構造体はデフォルトでスタックに配置され、スタックは一般的にスペースの面ではるかに制限されています。そのため、このように構造体を大量に作成することは問題になる可能性があります。

しかし、実際には、それほど大したことではないと思います。それらの多くを持っている場合、それらはどこか(ヒープ上の)クラスインスタンスの一部である可能性があります。

Structはこのアプリケーションに適しているようです。

「これらの値を保持する必要がある」ことを忘れないでください。ヒープ上のストレージ、おそらくクラスインスタンスの配列フィールドを意味します。

注意すべき点の1つは、これによりラージオブジェクトヒープが割り当てられることです。しかし、このヒープがどのようにデフラグするかはそれほど明確ではありませんが、非常に長生きするオブジェクトの場合はおそらく問題ではありません。

これらの数百万のデータ型でクラスを使用すると、この型の操作で発生する可能性のある逆参照のせん断量が高くなる可能性があります。

原則として、間接型の数を減らすため、パフォーマンスのために、同じタイプのエイリアスされていない(つまり、共有されていない)データの大きな配列を構造体に保存するのが最適です。 ( when-are-structs-the-answer も参照してください)。クラスと構造体の正確なパフォーマンスの違いは、使用法によって異なります。 (たとえば、操作では、構造体の一部にしかアクセスしませんか?一時的なコピーをたくさん行いますか?構造体が小さい場合は常に使用した方が良いでしょうが、大きければ、一時的なコピーを作成すると速度が低下します。不変にすることで、値を変更するには常にすべてをコピーする必要があります。)

疑わしい場合は測定します。

このような測定では明らかにならない可能性のある長期的な影響に関心があるため、そのような配列は大規模オブジェクトヒープに格納されている可能性が高く、破棄して再割り当てするのではなく再利用する必要があることに注意してください。 ( CRL Inside Out:Large Object Heap Uncovered を参照してください。)

呼び出しで大きなサイズの構造体を渡す場合、コピーを避けるためにref引数でそれらを渡すことができます。

値型(構造体)は、ヒープに頻繁に割り当てられない型に適しています。つまり、ほとんどが別の参照または値型に含まれています。

指定したVector3の例は完璧な例です。ヒープにVector3がぶら下がることはめったにありません。ほとんどの場合、ヒープにある型に含まれるか、ローカル変数として使用されます。その場合、スタックに割り当てられます。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top