|
|
連載:[完全版]究極のC#プログラミング
Chapter15 LINQとクエリ式
川俣 晶
2010/03/17 |
|
|
15.16 from句とjoin句のパフォーマンス
さて、join句は制約が大きいことから、できればfrom句を使いたいと思う読者もいるだろう。はたして、from句とjoin句の差はどれぐらいあるのだろうか?
ここでは、先のリスト15.17を少し変更し、クエリ式からIdの値が何回参照されているかを調べてみよう(リスト15.19参照)。
using System;
using System.Linq;
class Program
{
class 商品情報
{
private int id;
public static int ReadCount = 0;
public int Id
{
get { ReadCount++; return id; }
set { id = value; }
}
public string 名前;
public int 定価;
}
class 商品販売価格
{
private int id;
public static int ReadCount = 0;
public int Id
{
get { ReadCount++; return id; }
set { id = value; }
}
public int 価格;
}
static void Main(string[] args)
{
(商品情報データと商品販売価格データの定義は
リスト15.17と同じなので省略)
#if false // from句を試す場合はtrueに書き換える
var query = from x in 商品情報データ
from y in 商品販売価格データ
where x.Id == y.Id
select new { Name = x.名前, Price = y.価格 };
#else
var query = from x in 商品情報データ
join y in 商品販売価格データ on x.Id equals y.Id
select new { Name = x.名前, Price = y.価格 };
#endif
foreach (var 商品 in query) {
Console.WriteLine("{0} {1:C}", 商品.Name, 商品.Price);
}
Console.WriteLine(
"商品情報.ReadCount={0},商品販売価格.ReadCount={1}",
商品情報.ReadCount, 商品販売価格.ReadCount);
}
}
|
|
リスト15.19 Idの参照回数を調べる |
…
商品情報.ReadCount=9,商品販売価格.ReadCount=9
|
|
リスト15.19の実行結果(from句の場合) |
…
商品情報.ReadCount=3,商品販売価格.ReadCount=3
|
|
リスト15.19の実行結果(join句の場合) |
この結果を見てわかるとおり、from句を2つ使った場合、クエリ対象の情報は、
ソース1の個数(3)× ソース2の個数(3)× 2 = 18回
|
|
の参照だが、join句を使用した場合は、
ソース1の個数(3)+ ソース2の個数(3)= 6回
|
|
しか参照されていない。これは、クエリ時のデータ参照の回数がfrom句では掛け算で増えるのに対して、join句では足し算で増えることを意味する。つまり、データの個数が増えれば増えるほど回数の差は劇的に増していく。
もちろん、データを参照する回数だけでパフォーマンスが決まるわけではない。では、具体的な時間差はどの程度あるのだろうか? 次のリスト15.20はそれを調べるために作成したソースコードである。
using System;
using System.Linq;
class Program
{
(商品情報と商品販売価格の定義はリスト15.17と同じなので省略)
static void Main(string[] args)
{
(商品情報データと商品販売価格データの定義は
リスト15.17と同じなので省略)
var query1 = from x in 商品情報データ
from y in 商品販売価格データ
where x.Id == y.Id
select new { Name = x.名前, Price = y.価格 };
var query2 = from x in 商品情報データ
join y in 商品販売価格データ on x.Id equals y.Id
select new { Name = x.名前, Price = y.価格 };
const int COUNT = 1000000;
DateTime start1 = DateTime.Now;
for (int i = 0; i < COUNT; i++) foreach (var 商品 in query1) { }
Console.WriteLine("from句: {0}", DateTime.Now - start1);
DateTime start2 = DateTime.Now;
for (int i = 0; i < COUNT; i++) foreach (var 商品 in query2) { }
Console.WriteLine("join句: {0}", DateTime.Now - start2);
}
}
|
|
リスト15.20 from句とjoin句の時間差を調べる |
from句: 00:00:03.5363536
join句: 00:00:01.9231923
|
|
リスト15.20の実行結果 |
デバッグビルド時。筆者のPCでの結果。 |
このように、処理時間としても、歴然とした差が見て取れる。また、データの個数が増えれば、差はさらに拡大するだろう。両者には歴然とした効率の差があると考えてよいだろう。join句が使用できるときは、join句の利用がお薦めである。
Insider.NET 記事ランキング
本日
月間