当我对代码进行基准测试时,我注意到第一次运行太慢,下一次运行太快。 原因是什么?
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
有没有办法即使在第一次运行时也能始终获得最大速度?
您正在测量开销抖动。 恰好及时。 在表达式的情况下,它主要是磁盘开销,其ngen-ed代码需要从System.Core.ni.dll文件加载到RAM中。 或者换句话说,您正在衡量硬页面错误的成本。 它将驻留一段时间,这就是为什么您第二次及以后调用其构造函数时它很快。
不,您始终必须支付此费用。
这是因为C#是一种"及时编译"的语言。
我希望在第一次迭代中,代码被动态编译成特定于机器的代码,并放入缓存中。对于下一次迭代,编译代码的开销不再存在,因为编译的代码已从缓存中取出。
可能还有其他原因与缓存预热有关,但第一个原因可能是原因。
您应该重复使用计时器并使用 Stop 函数才能正确使用计时器。
即类似于这样的东西:
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();
}