基准在C#中小code的样品,可以在此实现得到改善呢?在此、基准、样品、code

2023-09-02 10:19:46 作者:风之殇

很多时候,所以我发现自己的标杆code一小块一小块,看看哪些implemnetation是最快的。

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

很多时候我看到评论说,基准code不考虑jitting或垃圾收集器。

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
});

这是否实施有什么破绽?是不是不够好,表明implementaion X是不是实施ÿ快过ž迭代?你能想到的任何方式,你会改善吗?

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?

修改 它的pretty的明确表示,基于时间的方法(而不是迭代),是preferred,没有任何人有任何的实现在那里的时候检查不会影响性能?

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?

推荐答案

下面是修改后的功能:所推荐的社区,可随时修改本的一个社区的wiki。

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

static void Profile(string description, int iterations, Action func) {
    // 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);
}