我想测试算法的不同C#实现的执行时间。由于测试环境(我的计算机)有几个不受我控制的环境变量(如操作系统时间切片),我想获得大量数据点,然后查看分布。基本上,我想多次运行算法,测量每个算法的时间,然后以某种方式汇总结果。
代码看起来像这样:
public void TestSpeed()
{
var sw = new System.Diagnostics.Stopwatch();
MyTestAlgorightm(); // "warm up" system
for (var i = 0; i < 10000; i++)
{
sw.Reset();
sw.Start();
MyTestAlgorightm();
sw.Stop();
AddExecutionDuration(sw.ElapsedTicks);
}
AggregateResults();
}
然而,当我看结果时,他们似乎有点欺骗......我得到这样的时间:
84,23,19,22,19,18,17,17,......
我总是看到这种模式,第一次通话(实际上是第二次,在&#34;热身&#34;之后)需要一个&#34; long&#34;时间,然后后续呼叫都相对较快,并且都需要相同的持续时间才能运行。
我的猜测是,我所看到的与分支预测相似(我知道此代码中没有分支,但可能类似......),如this excellent question所示。< / p>
如果是这种情况,那么有没有办法将其关闭&#34;所以我可以看到通常每次从生产代码中调用MyTestAlgorithm()
需要多长时间,但是在此时间测试中仍能连续多次调用它以便我可以收集指标?
如果它不是类似于分支预测的东西,那么导致第一次定时呼叫需要更长时间的原因是什么?或者换一种说法,为什么后续呼叫运行得更快?
由于有人说,在不知道MyTestAlgorithm()
包含哪些内容难以回答这个问题(公平点)的情况下,这里是我测试的简化示例:
private AlgorithmTest _test;
private PropertyInfo _pi;
private int MyTestAlgorithm()
{
if (_pi == null)
{
_pi = typeof (AlgorithmTest).GetProperty("Prop1");
_test = new AlgorithmTest() {Prop1 = 42};
}
return (int)_pi.GetValue(_test);
}
public class AlgorithmTest
{
public int Prop1 { get; set; }
}
这是我的测试号码:
5,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,......
请注意,if
的正文未定时,因为它仅在&#34;预热&#34;期间第一次执行,然后结果被缓存。