最初に断わっておくと以下の実験はベンチマークのつもりで行ったのではなく、性能理解の目的で行っています。
ベンチマーク値としては何の意味もありません。従って環境によって値その他に変化があると思います。
Linq の特徴を調べる分には十分だと思います。
Dataset を用いての結果は参考程度と思ってください、Dataset も xsdファイル にテーブルをドラッグドロップしただけです。
Linq to SQL はループ1回目とループ2~9回目平均の差分をとると、ほぼ一定のロス分があります。
初回のロス分という意味では、 DataContext のコンストラクタの中で ConnectionString の取得もしています、Connecttion.Open でデータベースとの接続も行われます、これらはキャッシュされたりプールされたりして2回目以降は短時間で済みます。
それでもロス分は不足するのですが分析ツールで調べてみるとGetEnumeratorで時間がかかっているようです、初回のみExpressionTreeの解析からSQL分を生成してキャッシュしているのではないかと思います。
推測ですがExpressionTreeの解析からSQL分を生成する部分には思ったよりコストがかかることを覚悟しなければいけないようですが、キャッシュ効果により複数回使うことで余りあるメリットを生み出すことになります。
図のY軸はmSec、X軸はデータ件数です。使用したテーブルはその6のTable_1です。
「ctor+Open」は今コメントになっているコネクションオープンを生かし、実際のクエリをコメントにした結果です。
一回の実行は Linq と Dataset 別々の Exe で実行しています、尚、サーバーのキャッシュを考慮して、Linq を一回実行してから Linq(計測) DataSet(計測) の順で行っています。
for (int i = 0; i < 10; i++)
{
Stopwatch t1 = new Stopwatch();
t1.Start();
{
using (var context = new LinqTestDataContext())
{
//context.Connection.Open();
var query = from a in context.Table_1 select a;
string text;
foreach (var a in query)
{
text = a.ID.ToString() + "," + a.TEXT1 + "," + a.TEXT2;
}
}
}
t1.Stop();
Debug.WriteLine(t1.ElapsedMilliseconds.ToString());
}
for (int i = 0; i < 10; i++)
{
Stopwatch t2 = new Stopwatch();
t2.Start();
{
using (var dataset = new DatasetTest())
using (var ta = new DatasetTestTableAdapters.Table_1TableAdapter())
{
//ta.Connection.Open();
ta.Fill(dataset.Table_1);
string text;
foreach (var a in dataset.Table_1)
{
text = a.ID.ToString() + "," + a.TEXT1 + "," + a.TEXT2;
}
}
}
t2.Stop();
Debug.WriteLine(t2.ElapsedMilliseconds.ToString());
}