1. ホーム
  2. c#

[解決済み] 構造体とクラス

2023-01-21 10:07:59

質問

コードで10万個のオブジェクトを作成しようとしています。それらは小さいもので、2つか3つのプロパティしか持っていません。私はそれらを一般的なリストに入れ、それらがあるとき、私はそれらをループし、値をチェックします。 a をチェックし、おそらく値を更新します。 b .

これらのオブジェクトは、クラスとして作成する方が速いですか、それとも構造体として作成する方が良いですか?

EDIT

a. プロパティは値型(文字列は除く?)です。

b. バリデートメソッドを持つかもしれない(まだ確定していない)。

編集2

ヒープ上のオブジェクトとスタック上のオブジェクトは、ガベージコレクタによって等しく処理されるのでしょうか、それとも異なる動作をするのでしょうか?

どのように解決するのですか?

<ブロッククオート

それは より速く として作成する方が速いですか?

その質問の答えを決定できるのはあなただけです。両方の方法を試してみてください。 測る を測定してください。そうすれば、その変更が関連するシナリオの実際のユーザーに意味のある影響を与えるかどうかがわかります。

構造体はより少ないヒープ メモリを消費します (なぜなら構造体は より小さい であり、コンパクト化しやすいからであって、スタック上にあるからではありません)。しかし、参照コピーよりもコピーに時間がかかります。メモリ使用量や速度に関するパフォーマンス指標がどのようなものか知りませんが、ここにはトレードオフがあり、それが何であるかを知っているのはあなた自身なのです。

それは より良い として作成するのが良いのでしょうか?

クラスか、構造体か。経験則から言うと もしオブジェクトが:

1. 小さい

2. 論理的に不変の値

3. たくさんある

それなら、構造体にすることを考えます。そうでなければ、参照型にこだわりますね。

構造体のフィールドを変更する必要がある場合は、フィールドが正しく設定された新しい構造体全体を返すコンストラクタを構築する方がよいでしょう。その方が若干遅いかもしれませんが(測定してください!)、論理的にははるかに簡単です。

ヒープとスタック上のオブジェクトはガベージコレクタによって同じように処理されるのでしょうか?

いいえ。 ので、同じではありません。 スタック上のオブジェクトはコレクションのルートだからです。 . ガベージコレクタは、「スタック上のこのオブジェクトは生きているか」と尋ねる必要がありません。 その答えは常に「はい、スタック上にあります」だからです。 保つ というのは、スタックは実装の詳細だからです。 ジッターは、たとえば、通常はスタック値であるものを登録する最適化を導入することが許されており、その後、それは決してスタック上にないので、GC はそれがまだ生きていることを知りません。登録されたオブジェクトは、それを保持しているレジスタが再び読み込まれることがないと同時に、その子孫を積極的に収集させることができます)。

しかし、ガベージコレクタは は、生きていることが知られているオブジェクトを生きているものとして扱うのと同じように、スタック上のオブジェクトを生きているものとして扱わなければなりません。スタック上のオブジェクトは、生きている必要があるヒープに割り当てられたオブジェクトを参照できるので、GC は生きているセットを決定する目的のために、スタックオブジェクトを生きているヒープに割り当てられたオブジェクトのように扱わなければなりません。 しかし、明らかにそれらは ではありません。 なぜなら、それらはそもそもヒープ上に存在しないからです。

これは明確ですか?