有人可以帮我找到这段代码的瓶颈吗?

时间:2016-02-11 17:31:52

标签: c# entity-framework optimization

我在一个运行大约5000次的循环中有以下代码块。

IQueryable<IGrouping<int?, StatusLog>> allLogs = db.StatusLogs
    .Where(sl => sl.ID.Value.Equals(foo))
    .GroupBy(sl=>sl.bar);

List<StatusLog> statusLogs = new List<StatusLog>();

foreach (var group in allLogs)
{
    // do stuff that adds to statusLogs
}

if (statusLogs.Count > 0)
{
    // do stuff
}

我试图在代码中找到一个瓶颈,看似没有理由需要大约50毫秒。

即使allLogs为空并且没有组,也需要50毫秒才能从

步进
foreach (var group in allLogs)

if (statusLogs.Count > 0)

单步执行var groupin allLogs的评估只需要大约3毫秒,那么当foreach循环内的代码没有进入下一个语句时,如何跳转到下一个语句需要50毫秒。甚至跑?

2 个答案:

答案 0 :(得分:2)

将其溢出到db访问,然后将每个for循环和时间(使用StopWatch类)

var allLogs = db.StatusLogs
    .Where(sl => sl.ID.Value.Equals(foo))
    .GroupBy(sl=>sl.bar).ToList();// tolist forces query to run now

foreach (var group in allLogs)
{
    // do stuff that adds to statusLogs
}

答案 1 :(得分:1)

那是因为allLogs本质上是 lazy - 当foreach中首次枚举时,它实际上会点击数据库(参见&#34;延迟查询执行&#34; here)。如果您像以下一样事先实现了集合,您将看到它快速逐步完成foreach

db.StatusLogs
    .Where(sl => sl.ID.Value.Equals(foo))
    .GroupBy(sl=>sl.bar)
    .ToList();  // <-- pull the query results into memory