2009年12月15日

LINQのToListメソッド

  
Ito Blogの LINQ における ToList メソッドにコメントできないみたいので、 こちらに書きます。

IEnumerable<T> を返すメソッドなんかを自作して、それをどんどんつなげて行くと最後に複雑なLINQのクエリが実行されて、ものすごく遅くなることがあるんですよね。

なので、意識的に ToList() などを呼んで即時実行させるときがあります。これだけで、速度がグンと速くなる場合があります。

ということで、List<T>にする必要はないけど、ToList()を呼び出すこともあります。


この記事へのコメント
自分で試さず質問で悪いのですが、
複雑なLINQクエリが理由で遅くなるなら、
IQueryableで作れば改善されるってことは無いのでしょうか?

具体的に言うと、WhereとかSelectを式木で受け取って、最後のforeachでコンパイルして実行するようにです。
Posted by ground at 2009年12月15日 22:04
ああ、僕の表現が間違ってました。
複雑なLINQクエリだから、ToList()を書くのではなく、
IEnumerableの複雑な連鎖を止めるために、ToList()を書く場合があるということです。
IEnumerable<int> items = ...;
for ( ... ) {
items = DoExecute(items);
...
}
みたいなコードで、DoExecuteの中の書き方によっては、
DoExecuteの中で利用しているメソッドの呼び出し回数が、異なってきます。
どうして、メソッドの呼ばれる回数が異なるのかまで調べきれれていません。
なので、Expression の Compileとは直接関係ないと思われます。

まあ、こんなコードを書く僕が悪いのですが...

IQueryableのほうは、時間があったら試してみたいと思いますが、
かなり面倒そうですね。
Posted by gushwell at 2009年12月16日 19:54
コメントをありがとうございます。
私のブログのコメント機能についてですが、会社の公式ブログで、コメント禁止という設定になっているため、皆さんには、ご不便をおかけしております。

この場にて、ToListを意図的に実行するケースについて、コメントを書いたのですが、長くなってしまったので、改めて私のブログにまとめました。

あくまで gushwell さんの仰るケースの補足というスタンスですが、もし、違っている部分などありましたら、またご指摘いただければ幸いです。
Posted by 伊藤達也 at 2009年12月17日 10:34
> ワンライナーで記述する式に ToList メソッドをかませることが有効である場合は稀であるはずです

深く同意します。

伊藤さんが言及されているように、クエリの結果としてのシーケンスに対し、遅延実行されない Sum(), Max(), Length()などを, 何回も呼ぶのはコスト高になるので、こういう場合は、ToList()したほうが良いですね。
Posted by Gushwell at 2009年12月17日 21:01
 

この記事へのトラックバックURL

http://trackback.blogsys.jp/livedoor/gushwell/51942928