在C#中对小代码示例进行基准测试,这个实现可以改进吗? [英] Benchmarking small code samples in C#, can this implementation be improved?

查看:14
本文介绍了在C#中对小代码示例进行基准测试,这个实现可以改进吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Quite often on SO I find myself benchmarking small chunks of code to see which implemnetation is fastest.

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

Quite often I see comments that benchmarking code does not take into account jitting or the garbage collector.

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

I have the following simple benchmarking function which I have slowly evolved:

  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 快?你能想出什么方法来改善这一点吗?

Does this implementation have any flaws? Is it good enough to show that implementaion X is faster than implementation Y over Z iterations? Can you think of any ways you would improve this?

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

EDIT Its pretty clear that a time based approach (as opposed to iterations), is preferred, does anyone have any implementations where the time checks do not impact performance?

推荐答案

这里是修改后的功能:根据社区的推荐,随时修改它的社区维基.

Here is the modified function: as recommended by the community, feel free to amend this its a community wiki.

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 之外运行测试.最后一部分很重要,因为即使在发布模式下,JIT 也会通过附加调试器进行优化.

Make sure you compile in Release with optimizations enabled, and run the tests outside of Visual Studio. This last part is important because the JIT stints its optimizations with a debugger attached, even in Release mode.

这篇关于在C#中对小代码示例进行基准测试,这个实现可以改进吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆