经常如此,我发现自己对小块代码进行基准测试,以确定哪种实现最快.

我经常看到一些 comments ,说基准测试代码没有考虑jitting或垃圾收集器.

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

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

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

EDIT个 很明显,基于时间的方法(相对于迭代)是首选的,有没有人有时间判断不会影响性能的实现呢?

推荐答案

以下是修改后的功能:根据社区的建议,可以在社区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;
}

确保你compile in Release with optimizations enabled, and run the tests outside of Visual Studio岁.最后一部分很重要,因为即使在发布模式下,JIT也会在附加了调试器的情况下进行优化.

.net相关问答推荐

如何使用.NET8MapIdentityApi设置OpenApi操作ID

使用托管身份而不是检测密钥配置Application Insights

EGC / 文本元素上的 .NET String.Split

C#.Net 中的可选返回

.gitignore 和 Visual Studio 项目:忽略 bin/Debug 目录但不忽略 bin/Release 目录

process.WaitForExit() 异步

在c#中计算中位数

如何中止任务,如中止线程(Thread.Abort 方法)?

如何明智地使用 StringBuilder?

DateTime.TryParseExact() 拒绝有效格式

C# 属性实际上是方法吗?

将接收到的对象转换为 List 或 IEnumerable

Dapper 是否支持 SQL 2008 表值参数?

在 .NET 中填充整数列表

SQLParameter 如何防止 SQL 注入?

迭代器和枚举器的区别

Visual Studio 2017 和 2019 突出显示滚动条中所选单词的出现

在 IIS 中访问 .svc 文件时出现 HTTP 404

您可以将 Microsoft Entity Framework 与 Oracle 一起使用吗?

嵌套捕获组如何在正则表达式中编号?