読み取りのロック競合を最小限に抑えようとする並行コレクションを最適化しようとしています。最初のパスは、リンクされたリストを使用していました。これにより、多くの同時読み取りがブロックされずに続行できる一方で、書き込みのみをロックできました。これは、カスタムIEnumerator
を使用して次のリンク値を生成しました。コレクションの反復をプレーンと比較し始めると、実装が約半分の速さであることにList<T>
気付きました ( 1 from x in c select x
*m* アイテムのコレクションでは、コレクションで 24ミリ秒、コレクションで49 ミリ秒)。List<T>
そこで、aを使用ReaderWriteLockSlim
して、読み取り時の競合を少し犠牲にして、aList<T>
を内部ストレージとして使用できるようにしようと考えました。繰り返しの開始時に読み取りロックを取得し、完了時にそれを解放する必要があるため、最初に my の yield パターンを実行し、 internalIEnumerable
に対してforeachList<T>
を実行しました。今、私は66msしか得ていませんでした。
List が実際に何をするかを調べたところ、内部ストアと、インデックスを前方に移動して現在のインデックス値を返すT[]
カスタムが使用されています。IEnumerator
現在、ストレージとして手動で使用T[]
すると、メンテナンス作業が大幅に増えますが、マイクロ秒を追いかけています。
ただしIEnumerator
、配列のインデックスの移動を模倣しても、できることは約~38ms でした。では、List<T>
その秘密のソースを提供するものは何ですか? あるいは、イテレータのより高速な実装は何ですか?
更新:私の主な速度の犯人は、List<T>
明らかにリリース コンパイルである一方で、デバッグ コンパイルを実行していたことが判明しました。リリースでは、私の実装はまだ よりも少し遅いですがList<T>
、モノラルではより高速になりました。
友人から得たもう 1 つの提案は、BCL は GAC にあり、システムによってプリコンパイルできるため、高速であるというものです。その理論をテストするには、私のテストをGACに入れる必要があります。