1

オブジェクトへのlinqに関して、.Where(x => x ....)を使用し、その後すぐに.SkipWhile(x => x ...)を使用すると、パフォーマンスが低下します。コレクションを2回?

Where句またはSkipWhile句にすべてを入れる方法を見つける必要がありますか?

4

5 に答える 5

7

イテレータをチェーン化することにより、わずかな非効率が発生しますが、実際には非常に軽微です。(特に、一致する各アイテムは両方の演算子に表示されますが、バッファーに入れられることはありません。LINQto Objectは、一致するすべてのアイテムの新しいリストを作成して、それを実行SkipWhileすることはありません。)

これがパフォーマンスにとって非常に重要な場合は、そもそもLINQを使用しないことで、速度がわずかに上昇する可能性があります。それ以外の場合は、最初に最も単純なコードを記述し、ボトルネックであることが証明された場合にのみ、このようなマイクロ最適化について心配してください。

于 2010-02-02T22:37:47.937 に答える
2

ほとんどのことと同じように、答えはあなたが何をしているかに依存するということです。同じオブジェクトを操作する場所が複数ある場合は、たとえば&&と組み合わせる価値があります。

ほとんどのLINQオペレーターは、オペレーターごとにコレクション全体を反復処理することはなく、1つのアイテムを処理して、次のオペレーターに渡すだけです。これには、ReverseやOrderByなどの例外がありますが、通常、たとえばWhereとSkipWhileを使用している場合は、一度に1つのアイテムを処理するチェーンがあります。これで、最初のWhereステートメントで一部のアイテムが明らかに除外される可能性があるため、SkipWhileは、前の演算子を通過するまでアイテムを表示しません。

私の個人的な好みは、明確にするために演算子を分離し、パフォーマンスが問題になる場合にのみ演算子を結合することです。

于 2010-02-02T22:37:12.090 に答える
2

WhereとSkipWhileを使用しても、「コレクションを2回調べる」ことにはなりません。LINQtoObjectsはプルモデルで機能します。結合されたクエリを列挙すると、SkipWhileはそのソースに要素を要求し始めます。そのソースはWhereであるため、Whereはソースに要素を順番に要求し始めます。したがって、SkipWhileは、Where句を渡すすべての要素を表示しますが、それが進むにつれてそれらを取得します。結果として、LINQは元のコレクションに対してforeachを実行し、WhereフィルターとSkipWhileフィルターの両方を通過する要素のみを返します。これには、コレクションに対する1回のパスのみが含まれます。

2つのイテレータが関係しているため、効率がわずかに低下する可能性がありますが、それが重要になる可能性は低いです。コードを明確にする必要があります(現在行っているように)。明確なバージョンがパフォーマンスの問題を引き起こしていると思われる場合は、を測定してから、句を組み合わせてみてください。

于 2010-02-02T22:37:40.293 に答える
2

とを使用するときに、コレクションを2回確認することはありませんWhereSkipWhile

Whereメソッドは、出力を一度に1アイテムずつメソッドにストリーミングします。SkipWhile同様に、SkipWhileメソッドは、出力を後続のメソッドに一度に1アイテムずつストリーミングします。

(コンパイラーがバックグラウンドでメソッドごとに個別のイテレーター・オブジェクトを生成するため、わずかなオーバーヘッドが発生します。ただし、コンパイラーが生成するイテレーターのオーバーヘッドが心配な場合は、そもそもLINQを使用しないでしょう。)

于 2010-02-02T22:37:54.227 に答える
1

いいえ、(基本的に)パフォーマンスの低下はありません。それが怠惰な(延期された)実行のすべてです。

于 2010-02-02T22:37:00.980 に答える