[解決済み] LINQメソッドの実行時の複雑さ(Big-O)にはどのような保証があるのでしょうか?
質問
私は最近LINQを使い始めたのですが、LINQのメソッドの実行時の複雑さについて言及したものを見たことがありません。明らかに、ここには多くの要因があるので、議論を単純な
IEnumerable
LINQ-to-Objects プロバイダーに限定して説明します。さらに、任意の
Func
セレクタ/ミューテータ/その他として渡されるものは、安価なO(1)操作であるとします。
シングルパス操作のすべてが明白なようです(
Select
,
Where
,
Count
,
Take/Skip
,
Any/All
など)は、シーケンスを一度だけ歩く必要があるので、O(n)になります。ただし、これでも怠慢には影響されます。
より複雑な演算については、より不明確です。集合のような演算子 (
Union
,
Distinct
,
Except
など) を使って作業します。
GetHashCode
をデフォルトで使うので、内部でハッシュテーブルを使っていると考えるのが妥当で、一般にこれらの演算も O(n) になります。では
IEqualityComparer
?
OrderBy
はソートが必要なので、O(n log n)を見ている可能性が高いです。すでにソートされている場合はどうでしょうか?もし私が
OrderBy().ThenBy()
と言って、両方に同じキーを提供するのはどうでしょうか?
私が見ることができたのは
GroupBy
(そして
Join
) を、ソートかハッシュのどちらかを使って表示します。どちらなのでしょうか?
Contains
は、O(n)であろう。
List
では O(1)ですが
HashSet
- は、LINQが基礎となるコンテナをチェックして、高速化できるかどうかを確認するのでしょうか?
そして本当の質問ですが、これまで私は、操作がパフォーマンス的であることを信じていました。しかし、それを信頼してもよいのでしょうか。たとえば、STL コンテナでは、すべての操作の複雑さを明確に指定しています。.NETライブラリの仕様に、LINQのパフォーマンスに関する同様の保証はあるのでしょうか?
より多くの質問(コメントへの応答)。
オーバーヘッドについてあまり考えたことがありませんでしたが、単純なLinq-to-Objectsではあまりないと思っていました。CodingHorror の投稿は Linq-to-SQL について述べていますが、クエリの解析と SQL の作成がコストを追加することは理解できます - オブジェクト プロバイダーにも同様のコストがあるのでしょうか。もしそうなら、宣言型または関数型の構文を使用している場合、それは異なるのでしょうか?
どのように解決するのですか?
保証はほとんどありませんが、いくつかの最適化があります。
-
インデックス付きアクセスを使用する拡張メソッド、例えば
ElementAt
,Skip
,Last
またはLastOrDefault
を実装しているかどうかを確認します。IList<T>
を実装しているかどうかを調べ、O(N)ではなくO(1)のアクセスを得られるようにします。 -
は
Count
メソッドはICollection
の実装をチェックし、この操作が O(N) ではなく O(1) になるようにします。 -
Distinct
,GroupBy
Join
そして、私はセット・アグリゲーション・メソッド (Union
,Intersect
とExcept
) はハッシュを使うので、O(N²) ではなく O(N) に近くなるはずです。 -
Contains
がチェックします。ICollection
の実装があるかどうかをチェックし、その結果 は のような、基礎となるコレクションが O(1) である場合、O(1) になります。HashSet<T>
のように、基礎となるコレクションが O(1) であれば、は O(1) になる可能性がありますが、これは実際のデータ構造に依存し、保証されるものではありません。 ハッシュセットはContains
メソッドをオーバーライドするため、O(1)となります。 -
OrderBy
メソッドは安定したクイックソートを使用するので、O(N log N)平均ケースとなります。
組み込みの拡張メソッドのすべてではないにしても、ほとんどをカバーしていると思います。 Linq自体は効率的なデータ構造を利用しようとしますが、潜在的に非効率なコードを書くためのフリーパスではありません。
関連
-
[解決済み】指定されたキャストが有効でない?
-
[解決済み】GDI+、JPEG画像をMemoryStreamに変換する際にジェネリックエラーが発生しました。
-
[解決済み】スクリプトクラスが見つからないので、スクリプトコンポーネントを追加できない?
-
[解決済み】なぜこのコードはInvalidOperationExceptionを投げるのですか?
-
[解決済み] C#の正しいバージョン番号を教えてください。
-
[解決済み] NP、NP-Complete、NP-Hardの違いは何ですか?
-
[解決済み] WPFの場合、x:Name属性とName属性の違いは何ですか?
-
[解決済み] LINQは結果が空の場合、何を返すのですか?
-
[解決済み】ExpandoObjectの本当のメリットは何ですか?
-
[解決済み】big-O時間複雑度の高いアルゴリズムが低いアルゴリズムより好ましいと思うケースはありますか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] メンバー '<メンバー名>' にインスタンス参照でアクセスできない
-
[解決済み】"The ConnectionString property has not been initialized "を修正する方法
-
[解決済み】C# ASP.NET使用時に「WebClientのリクエスト中に例外が発生しました。
-
[解決済み] DBNullから他の型にオブジェクトをキャストすることができない
-
[解決済み】Sequence contains no matching element(シーケンスにマッチする要素がない
-
[解決済み】C# - パスに不正な文字がある場合
-
[解決済み】画像のペイントにTextureBrushを使用する方法
-
[解決済み】「namespace」なのに「type」のように使われる。
-
VSでscanfエラーを恒久的に解決するには、ソースファイルを作成し、自動的に#define _CRT_SECURE_NO_WARNINGS 1を追加してください。
-
[解決済み] LinqでIdのリストに基づいて複数のレコードを選択する