24

私が読んだことから、パフォーマンス上の理由から、特定のコレクションの列挙型を参照型ではなく変更可能な構造体にする設計上の決定が下されました。List.Enumerator は最もよく知られています。

配列を使用する古いコードを調査していたところ、C# 配列が参照型である汎用列挙子型として SZGenericArrayEnumerator 型を返すことを発見して驚きました。

他の非常に多くのパフォーマンスが重要なコレクションが代わりに可変構造体を使用しているときに、Array の汎用イテレータが参照型として実装された理由を誰かが知っているかどうか疑問に思っています。

4

2 に答える 2

38

私が読んだことから、パフォーマンス上の理由から、特定のコレクションの列挙型を参照型ではなく変更可能な構造体にする設計上の決定が下されました。

良い質問。

まず、あなたは正しいです。一般に、可変値型はコードの悪臭を放ちますが、この場合は正当化されます。

  • ミューテーションは、ユーザーからほとんど完全に隠されています。
  • 誰かが列挙子を紛らわしい方法で使用する可能性はほとんどありません。
  • 可変値型を使用すると、非常に一般的なシナリオで現実的なパフォーマンスの問題が実際に解決されます。

他の非常に多くのパフォーマンスが重要なコレクションが代わりに可変構造体を使用しているときに、Array の汎用イテレータが参照型として実装された理由を誰かが知っているかどうか疑問に思っています。

あなたが配列の列挙のパフォーマンスを気にするような人なら、そもそもなぜ列挙子を使うのでしょうか? これは念のための配列です。for普通の人のようにインデックスを反復するループを書くだけで、決して列挙子を割り当てません。(またはループ。ループ コレクションが配列であることがわかっている場合foreach、C# コンパイラはforeachループを同等のループに書き換えます。)for

そもそも配列から列挙子を取得する唯一の理由は、 を受け取るメソッドにそれを渡すIEnumerator<T>場合です。値の型を作成してからボックス化する費用を負担するのはなぜですか? 最初は参照型にしてください。

于 2012-02-07T21:15:15.990 に答える
3

配列は、C# コンパイラで特別な扱いを受けます。それらで使用すると、コンパイラはそれをループforeachに変換します。forしたがって、struct列挙子を使用してもパフォーマンス上の利点はありません。

List<T>一方、特別な処理を行わない単純なクラスであるため、構造体を使用するとパフォーマンスが向上します。

于 2012-02-07T21:14:57.147 に答える