クエリ式のパフォーマンス

きっかけは↓の記事なんですけども、クエリ式のパフォーマンスについての話を少々。
クエリ式で総当たり - NyaRuRuが地球にいたころ

先に、今日の話のまとめに相当するソースファイルを掲示↓。
http://ufcpp.net/study/csharp/source/Comprehension.cs

C# 3.0 のクエリ式は、ラムダ式とかIQueryableを駆使して色々と面白いことができるんで、高いポテンシャルを秘めてるんですけども、ここで話すのはもうちょっと単純な場合について。
クエリ式は、LINQ to object(単純な IEnumerable に対するクエリ)に話を限定して、from, where select くらいしか使わないような単純な場合には、foreach, if, yield return ですべて置き換え可能なんですよね。例えば、

var points =
  from x in Enumerable.Range(0, 100)
  from y in Enumerable.Range(0, 100)
  where x % 2 != 0
  where y % 3 != 0
  select new { x, y };

みたいな場合、

static IEnumerable<Point> Points()
{
  foreach (var x in Enumerable.Range(0, 100)
  foreach (var y in Enumerable.Range(0, 100)
  if (x % 2 != 0)
  if (y % 3 != 0)
  yield return new Point(x, y);
}

と書ける。イテレータは匿名メソッドで書けない(=匿名型を使えない)っていう欠点はありますが、パフォーマンスは下側のコードの方がよかったりします。

あと、条件式はできる限り前にあった方がパフォーマンスがよかったりします。例えば、上のコードよりも、

var points =
  from x in Enumerable.Range(0, 100)
  where x % 2 != 0
  from y in Enumerable.Range(0, 100)
  where y % 3 != 0
  select new { x, y };
static IEnumerable<Point> Points()
{
  foreach (var x in Enumerable.Range(0, 100)
  if (x % 2 != 0)
  foreach (var y in Enumerable.Range(0, 100)
  if (y % 3 != 0)
  yield return new Point(x, y);
}

の方がパフォーマンスはいいです。2つ目のループが回る回数が減るんで。が、from が一番上に固まってる場合と比べて、思った以上に見た目が悪い・・・

まあ、結論としては、IQueryable / ラムダ式を使って、from, where, select を foreach, if, yield return に展開&クエリの順序最適化をかけるようなライブラリが欲しいなぁ。