5

私は、1 つのデータベースと 1 つのデータベース テーブルに対して 1 つのエンティティを持つ、途方もなく単純な edmx モデルを持っています。ローカル仮想データベース サーバーからのすべてのレコードの順次取得のテスト。

using System;
using System.Linq;

namespace ConsoleApplication1
{
    using System.Diagnostics;

    private static readonly ConcurrentBag<long> Stats = new ConcurrentBag<long>();
    static void Main(string[] args)
    {
        for (int i = 0; i < 5; i++)
        {
            var sw = Stopwatch.StartNew();
            using (var ctx = new ScratchEntities())
            {
                foreach (var invoice in ctx.Invoices.Select(
                    s => new
                         {
                             s.Id,
                             s.Amount,
                             s.DueDate
                         }))
                {

                }
            }
            sw.Stop();
            Stats.Add(sw.ElapsedMilliseconds);
        }
        Console.WriteLine("Min {0}    Max {1}    Avg {2}", Stats.Min(), Stats.Max(), Stats.Average());

    }
}

EF 4 および 5 では、実行に約 2 ~ 2.5 秒かかりました。Nuget の EF6 にアップグレード、ほぼ 10 秒。

同様に、ctx.Invoices で foreach を使用すると、ctx.Invoices.Select(s=>new{all columns here}) で foreach を使用する場合と比較して、4 ~ 5 倍の時間がかかります。

困惑。

アップデート:

5回繰り返す

EF 6.0.1 最小 3082 最大 9231 平均 4462.8

EF 5.0.0 最小 1502 最大 2016 平均 1665.4

1M 行のすべての時間 (ミリ秒)。

.Net 4.5

更新 2:

105 のうち最初の 5 つのテストを破棄する

EF 6.0.1最小 2698 最大 4383 平均 3136

EF 5.0.0最小 1426 最大 2922 平均 1628

更新 3:

ここのアドバイスに従って TT テンプレートを再作成した後

EF 6.0.1最小 2589 最大 4279 平均 3027

ここで説明されているNGENでEF6をコンパイルした後

EF 6.0.1最小 2644 最大 4322 平均 3045.7

更新 4:

AsEnumerable に変更した後

EF 6.0.1最小 2661 最大 4658 平均 3134.6

4

1 に答える 1

3

EF6 では、既定のデータ取得動作をストリーミングからバッファリングに変更しました (理由については、こちらを参照してください)。バッファリングにより追加のオーバーヘッドが追加されます。これは、マッピングされていない CLR 型への射影や AsNoTracking 拡張メソッドを介した投影などの追跡なしのクエリを実行するときに特に顕著です。この問題を軽減するために、クエリごとにバッファリングをオフにするAsStreaming拡張メソッドを追加しました。AsStreaming を使用すると、EF5 のようなパフォーマンスが得られます。

于 2013-11-08T00:00:19.323 に答える