我创建了一个简单的类来对我的一些方法进行基准测试。但它准确吗?我对基准测试、计时等方面有点陌生,所以我想我可以在这里征求一些反馈。另外,如果它很好,也许其他人也可以使用它:)
public static class Benchmark
{
public static IEnumerable<long> This(Action subject)
{
var watch = new Stopwatch();
while (true)
{
watch.Reset();
watch.Start();
subject();
watch.Stop();
yield return watch.ElapsedTicks;
}
}
}
你可以这样使用它:
var avg = Benchmark.This(() => SomeMethod()).Take(500).Average();
有任何反馈吗?它看起来非常稳定和准确,还是我错过了什么?
最佳答案
它与简单基准测试的准确度差不多。但有些因素不在您的控制范围内:
- 从其他进程加载到系统上
- 基准测试之前/期间堆的状态
您可以针对最后一点做一些事情,基准测试是调用 GC.Collect
的罕见情况之一。可以防御。您可以预先调用一次 subject
来消除任何 JIT 问题。但这要求对 subject
的调用是独立的。
public static IEnumerable<TimeSpan> This(Action subject)
{
subject(); // warm up
GC.Collect(); // compact Heap
GC.WaitForPendingFinalizers(); // and wait for the finalizer queue to empty
var watch = new Stopwatch();
while (true)
{
watch.Reset();
watch.Start();
subject();
watch.Stop();
yield return watch.Elapsed; // TimeSpan
}
}
为了获得奖励,你的类(class)应该检查 System.Diagnostics.Stopwatch.IsHighResolution
field .如果它关闭,您只有一个非常粗略的(20 毫秒)分辨率。
但在普通 PC 上,后台运行着许多服务,它永远不会非常准确。
关于C#:这个基准测试类准确吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1507405/