衡量代码执行所需时间的最佳方法是什么?

我正在尝试确定哪种方法删除字符串最快。

我只是获得开始时间和结束时间并显示差异。

但是结果是如此多样,例如 如下所示,相同的方法可能需要60毫秒至231毫秒。

什么是获得更准确结果的更好方法?

替代文字[http://www.deviantsart.com/upload/1q4t3rl.png]

using System;
using System.Collections;
using System.Collections.Generic;

namespace TestRemoveFast
{
    class Program
    {
        static void Main(string[] args)
        {
            for (int j = 0; j < 10; j++)
            {
                string newone = "";
                List<string> tests = new List<string>();
                for (int i = 0; i < 100000; i++)
                {
                    tests.Add("{http://company.com/Services/Types}ModifiedAt");
                }

                DateTime start = DateTime.Now;
                foreach (var test in tests)
                {
                    //newone = ((System.Xml.Linq.XName)"{http://company.com/Services/Types}ModifiedAt").LocalName;
                    newone = Clean(test);
                }

                Console.WriteLine(newone);
                DateTime end = DateTime.Now;
                TimeSpan duration = end - start;
                Console.WriteLine(duration.ToString());
            }

            Console.ReadLine();
        }

        static string Clean(string line)
        {
            int pos = line.LastIndexOf('}');
            if (pos > 0)
                return line.Substring(pos + 1, line.Length - pos - 1);
                //return line.Substring(pos + 1);
            else
                return line;
        }
    }
}
Edward Tanguay asked 2020-08-12T05:40:40Z
10个解决方案
47 votes

您应该使用System.Diagnostics.Stopwatch,并且您可能需要考虑一个大样本。 例如,重复此测试约10,000次,然后取平均结果。 如果您科学地考虑它,这是有道理的。 样品越大越好。 您可以通过这种方式清除很多边缘情况,并真正了解核心性能。

要考虑的另一件事是,JIT编译和对象创建肯定会歪曲您的结果,因此请确保在适当的时间启动和停止Stopwatch,并在开始测试之前至少调用一次要测试的方法。 尝试尽可能仅将要测试的部分与其余代码分开。

Scott Anderson answered 2020-08-12T05:40:54Z
38 votes

三个简单的注释:

  1. 使用System.Diagnostics.Stopwatch。

  2. 不要在同一输入上分析代码一百万次。 尝试找到您期望的输入和概要分布。 那是真实输入的配置文件,而不是实验室输入的配置文件。

  3. 进入性能分析循环之前,请运行Clean方法一次,以消除JITting时间。 有时这很重要。

在这些注释中,注释1.和2.是最重要的。

如果不使用高分辨率计时器,则分析结果将毫无意义。 请注意,我们不会使用水钟为Usain Bolt计时。

如果不对真实输入进行测试,则分析结果将毫无意义。 请注意,碰撞测试的撞车以每小时35英里的速度驶入其他汽车,而不是撞上以每小时5英里的速度行驶的沼泽地制成的墙壁。

从而:

// expectedInput is string[1000000]
// populate expectedInput with real-world input
Clean(expectedInput[0]);
Stopwatch sw = new Stopwatch();
sw.Restart();          //So you dont have to call sw.Reset()
for (int i = 0; i < 1000000; i++) {
    string t = Clean(expectedInput[i]);
}
sw.Stop();
Console.WriteLine(sw.Elapsed);

一个复杂的注释:

如果您确实需要进行分析,请获取类似于ANTS的分析器。

jason answered 2020-08-12T05:41:54Z
7 votes

您可以使用秒表类。

秒表通过以下方式测量经过时间 计算底层的计时器滴答声 计时器机制。 如果安装 硬件和操作系统支持 高分辨率性能计数器 然后Stopwatch类使用 计数器来测量经过的时间。

var sw = new Stopwatch();

sw.Start();
// ...
sw.Stop();
João Angelo answered 2020-08-12T05:42:18Z
3 votes

如果您只担心在自己的代码中进行测试...请使用System.Diagnostics.Stopwatch

我通常更喜欢从我的代码中打破这种事情,并使用像RedGate的Performance Profiler这样的真正Profiler

Justin Niessner answered 2020-08-12T05:42:43Z
2 votes

在OS的内部有很多活动,很可能会弄乱您的时间测量。 为了提高测量时间的准确性,您应该多次执行测试,并从最终结果中删除最短和最长时间。 这种方法将排除可能影响代码执行时间的大多数外部因素,并在大多数情况下为您服务。 Stopwatch类用于测量时间,因为它比使用DateTime更准确。

您可以轻松地创建一个测试类以使其自动化。 我已经在自己的博客中发布了一个此类课程。 它可以比较两个C#代码片段/算法的性能。 您要做的就是重写Method1和Method2方法,在其中放置要测试的代码片段,并使用如下的测试类:

Test test = new CustomTest();
Console.WriteLine("\n==============================");
Console.WriteLine(test.Execute());
Console.WriteLine("==============================\n");
Pavel Vladov answered 2020-08-12T05:43:09Z
0 votes

您可能需要在此处应用一些统计技术来消除差异。 尝试将同一段代码运行1000次,然后花费平均时间,然后进行比较。 模拟通常采用某种方法来“清理”数字,这就是其中一种。

Extrakun answered 2020-08-12T05:43:29Z
0 votes

通常:不要看挂钟时间,而是看您的进程占用的CPU时间来确定运行时间。 尤其是对于仅是计算的事物而言,这将更加可靠,因为它将不受同时运行的其他进程的影响。

Joey answered 2020-08-12T05:43:49Z
0 votes

所有基于时钟的方法的麻烦在于,您永远不确定自己的时序。 无论您是否意识到,您都可以在自己的时间安排中:

  • 操作系统抢占处理器的延迟;
  • 上下文切换
  • 在程序等待数据时停顿;
  • 还有更多。

我并不是说所有这些都适用于此特定时间,而是通常适用于所有时间。 因此,您应该在考虑任何时间后,对替代代码执行多少个基本操作进行补充-对复杂性的一些考虑,而不是像我们通常所做的那样,忽略常数项。

在您的特定情况下,您应该瞄准更长的执行时间; 当您的时间不到一秒时,操作系统很可能会把您弄乱。 因此,运行10 ^ 6次迭代,并在足够的运行次数中使用平均值,可以为您提供有意义的平均值和方差计算。 并且,如果您采用这种方法,请确保您不会在第一次尝试结束后就已经加载了数据,从而无意中加快了第二次尝试的速度。 您必须确保10 ^ 6个试验中的每个试验都完全像第一个试验那样。

玩得开心

标记

High Performance Mark answered 2020-08-12T05:44:46Z
0 votes

我必须推荐Visual Studio Team Suite或开发版(或即将推出的Visual Studio 2010 Premium或Ultimate更好)中包含的高度分析器,作为最佳方法。 它是高度可配置的,功能强大的,使用起来非常简单,非常快,并且可以与本机代码和托管代码一起使用。 我对ANTS的工作流程不熟悉,但这似乎是另一种选择。 毫无疑问,使用探查器是对于开发人员关注其应用程序性能的唯一选择。 没有替代品,您真的不能让任何商业开发人员从事会严重影响分析器性能的工作。

但是,如果您对以下其中一项的测量感兴趣,则可能无法访问此类探查器,在这种情况下,Stopwatch类可以构成您的测量技术的基础:

  • 对项目表现感兴趣的学生或业余爱好者(出于经济原因,可能无法使用商业分析器)
  • 在公开发布的应用程序中,您可能希望对在UI线程上执行的代码段计时并报告统计信息,以确保操作不会对任何用户造成明显的延迟。 Office团队使用了这种方法取得了巨大的成功(Outlook 2007 SP2可以吗?),我知道Visual Studio团队至少在2010年版本中就有此代码。
Sam Harwell answered 2020-08-12T05:45:23Z
-1 votes

您还可以使用log4net,只需在要跟踪的内容上添加log.Info(“ Test”),即可在txt文件中找到所有信息以及执行该行的时间,例如:2018-12-13 10:02:16,704 [9] INFO Hms.Domain.Concrete.RoomsRepository [(null)] - Test在此处了解更多信息: [https://www.infoworld.com/article/3120909/application-development/how-to-work-with-log4net-in-c.html]

Krisi Suci answered 2020-08-12T05:45:43Z
translate from https://stackoverflow.com:/questions/2072361/what-is-the-best-way-to-measure-how-long-code-takes-to-execute