为什么第二个LINQ查询更快?

时间:2012-09-29 22:58:22

标签: performance linq

在此代码中:

static bool Spin(int WaitTime)
{
    Console.WriteLine("Running task {0} : thread {1}]",
        Task.CurrentId, Thread.CurrentThread.ManagedThreadId);
    Thread.Sleep(WaitTime);
    return true;
}

public void DemoPLINQLong()
{
    var SomeBigNumber = 1000000;
    var sequence = Enumerable.Range(0, SomeBigNumber);
    var sw = new Stopwatch();
    sw.Start();
    sequence.Where(i => Spin(SomeBigNumber));
    sw.Stop();
    var synchTime = sw.Elapsed;
    sw.Restart();
    sequence.Where(i => Spin(SomeBigNumber));
    sw.Stop();
    var asynchTime = sw.Elapsed;
    Console.WriteLine("Synchronous: {0}  Asynchronous: {1}",
        synchTime.ToString(), asynchTime.ToString());
}

结果是一致的: 同步:00:00:00.0021800异步:00:00:00.0000076

为什么第二次LINQ查询的速度要快几百倍?是否有某种缓存?怎么样?

1 个答案:

答案 0 :(得分:3)

DotNet在第一次执行任何操作时缓存并创建性能优化;这被称为Just In Time环境(JIT)。在后续调用相同的代码时,运行时环境可以重用现有的优化,这就是为什么你经常会看到几乎任何事情的第一次运行都比同一代码的后续运行慢得多。

关于发布代码的几个附注:

  1. 不确定“同步”和“异步”术语是指什么;这两个例子完全相同,没有关于它们的异步。
  2. 如果您不知道,由于LINQ的延迟执行的性质,在示例中没有评估LINQ。如果您将示例从sequence.Where(i => Spin(SomeBigNumber))更改为sequence.Where(i => Spin(SomeBigNumber)).ToList(),则可以看到此行为。其中,ToList()将强制评估LINQ谓词,Console.WriteLine将以Spin方法写入控制台。