我经常在 SO 上对小块代码进行基准测试,以查看哪种实现最快。

我经常看到基准测试代码没有考虑抖动或垃圾收集器的评论。

我有以下我慢慢发展的简单基准测试功能:

  static void Profile(string description, int iterations, Action func) {
        // warm up
        func();
        // clean up
        GC.Collect();

        var watch = new Stopwatch();
        watch.Start();
        for (int i = 0; i < iterations; i++) {
            func();
        }
        watch.Stop();
        Console.Write(description);
        Console.WriteLine(" Time Elapsed {0} ms", watch.ElapsedMilliseconds);
    }

用法:
Profile("a descriptions", how_many_iterations_to_run, () =>
{
   // ... code being profiled
});

这个实现有什么缺陷吗?是否足以证明在 Z 次迭代中实现 X 比实现 Y 快?你能想出什么方法来改善这一点吗?

编辑
很明显,基于时间的方法(而不是迭代)是首选,有没有人有任何时间检查不影响性能的实现?

最佳答案

这是修改后的功能:根据社区的建议,请随时修改它的社区维基。

static double Profile(string description, int iterations, Action func) {
    //Run at highest priority to minimize fluctuations caused by other processes/threads
    Process.GetCurrentProcess().PriorityClass = ProcessPriorityClass.High;
    Thread.CurrentThread.Priority = ThreadPriority.Highest;

    // warm up
    func();

    var watch = new Stopwatch();

    // clean up
    GC.Collect();
    GC.WaitForPendingFinalizers();
    GC.Collect();

    watch.Start();
    for (int i = 0; i < iterations; i++) {
        func();
    }
    watch.Stop();
    Console.Write(description);
    Console.WriteLine(" Time Elapsed {0} ms", watch.Elapsed.TotalMilliseconds);
    return watch.Elapsed.TotalMilliseconds;
}

确保在 Release 中编译 并启用优化,并在 Visual Studio 之外运行测试。最后一部分很重要,因为即使在 Release模式下,JIT 也会在附加调试器的情况下进行优化。

关于c# - 在C#中对小代码示例进行基准测试,这个实现可以改进吗?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/1047218/

10-14 20:10
查看更多