【问题标题】:Speed difference between first run and second run [duplicate]第一次运行和第二次运行之间的速度差异[重复]
【发布时间】:2015-04-26 15:03:53
【问题描述】:

当我对我的代码进行基准测试时,我注意到第一次运行太慢而下一次运行太快。是什么原因?

for (int i = 0; i < 10; i++)
{
    var timer = new Stopwatch();
    timer.Start();
    var expression = new Expression('x');
    Console.WriteLine(timer.ElapsedTicks);
}

结果

15096
6
0
1
1
1
1
1
0

有没有什么方法可以在第一次运行时始终获得最大速度?

【问题讨论】:

  • 你在实例化什么Expression 类? System.Linq.Expressions 中的那个是抽象的,我找不到任何其他具有带 char 参数的构造函数的类。
  • 哦。没有那个名为表达式的自定义类。我将它命名为表达式。@JacobBundgaard

标签: c# performance benchmarking


【解决方案1】:

您正在测量抖动开销。及时。在 Expression 的情况下,它主要是磁盘开销,它的 ngen-ed 代码需要从 System.Core.ni.dll 文件加载到 RAM 中。或者换句话说,您正在衡量硬页面错误的成本。它会驻留一段时间,这就是为什么它在您第二次和后续调用它的构造函数时速度很快。

不,您必须始终支付这笔费用。

【讨论】:

    【解决方案2】:

    我认为这是因为 C# 是一种“及时编译”语言。

    我希望在第一次迭代中,代码会被动态编译成机器特定的代码,并放入缓存中。对于接下来的迭代,编译代码的开销将不复存在,因为已编译的代码已从缓存中取出。

    可能还有其他原因与缓存变暖有关,但可能是第一个原因。

    【讨论】:

      【解决方案3】:

      您应该重复使用您的计时器并利用停止功能才能正确使用计时器。

      即类似的东西:

      var timer = new Stopwatch();        
      for (int i = 0; i < 10; i++)
      {
          timer.Start();
          var expression = new Expression('x');
          timer.Stop();
          Console.WriteLine(timer.ElapsedTicks);
          timer.Reset();
       }
      

      【讨论】:

      • 别忘了 timer.Restart :)
      猜你喜欢
      • 2020-03-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-07-12
      • 2017-06-16
      • 2017-05-20
      • 2018-11-03
      • 1970-01-01
      相关资源
      最近更新 更多