在C#中测量执行时间

我想测量一段代码的执行情况,我想知道最好的方法是什么?

选项1:

DateTime StartTime = DateTime.Now; //Code TimeSpan ts = DateTime.Now.Subtract(StartTime); string elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}", ts.Hours, ts.Minutes, ts.Seconds, ts.Milliseconds / 10); Console.WriteLine(elapsedTime, "RunTime"); 

选项2:使用System.Diagnostics;

  Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); //Code stopWatch.Stop(); // Get the elapsed time as a TimeSpan value. TimeSpan ts = stopWatch.Elapsed; // Format and display the TimeSpan value. string elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}", ts.Hours, ts.Minutes, ts.Seconds, ts.Milliseconds / 10); Console.WriteLine(elapsedTime, "RunTime"); 

这不仅仅是基准testing,它实际上是应用程序的一部分。 函数执行的时间是相关的数据。 但是,它不需要是primefaces的或者是超精确的。

哪个选项更适合生产代码,还是其他人使用不同的,也许更好?

Stopwatch类专门用于测量已用时间,并可能(如果硬件上可用)使用基础高频硬件定时器提供良好的粒度/精度。 所以这似乎是最好的select。

IsHighResolution属性可用于确定高分辨率时序是否可用。 根据文档,这个类为“精确可用”的Win32 API提供了一个精确时间的封装:

具体而言, Frequency字段和GetTimestamp方法可用于取代非托pipeWin32 API QueryPerformanceFrequencyQueryPerformanceCounter

这些Win32 API [这里]和链接的MSDN文档2有详细的背景。

高分辨率定时器

计数器是编程中用来指代递增variables的通用术语。 一些系统包括高分辨率的性能计数器,可以提供高分辨率的运行时间。

如果系统上存在高分辨率性能计数器,则可以使用QueryPerformanceFrequency函数以每秒计数的forms表示频率。 计数值取决于处理器。 例如,在某些处理器上,计数可能是处理器时钟的周期速率。

QueryPerformanceCounter函数检索高分辨率性能计数器的当前值。 通过在一段代码的开始和结尾调用该函数,应用程序本质上将该计数器用作高分辨率计时器。 例如,假设QueryPerformanceFrequency表示高分辨率性能计数器的频率是每秒50,000个计数。 如果应用程序立即在要定时的代码段之前和之后立即调用QueryPerformanceCounter ,则计数器值可能分别为1500个计数和3500个计数。 这些值表示执行代码时经过.04秒(2000个计数)。

StopWatch并不仅仅是更准确,而且DateTime.Now在某些情况下会给出不正确的结果。

考虑在夏令时切换期间会发生什么,例如使用DateTime.Now实际上可以给出否定的答案!

我通常使用StopWatch来处理这种情况。

从MSDN页面:

跑表

提供一组方法和属性,您可以使用这些方法和属性精确测量已用时间。

在下面的文章中,我使用它来比较LINQ和PLINQ的执行时间:

并行LINQ(PLINQ)与Visual Studio 2010

也不会伤害performance,因为你说这不是那么重要。 秒表似乎更合适 – 你只是减去时间,而不是从另一个date。 date的东西需要更多的内存和CPU时间来处理。 还有一些方法可以使代码更清洁,以防计划在多个地方重复使用代码。 想到超载。 我会寻找一个例子。 好的,从以下url窃取的代码:

http://stevesmithblog.com/blog/great-uses-of-using-statement-in-c/

 public class ConsoleAutoStopWatch : IDisposable { private readonly Stopwatch _stopWatch; public ConsoleAutoStopWatch() { _stopWatch = new Stopwatch(); _stopWatch.Start(); } public void Dispose() { _stopWatch.Stop(); TimeSpan ts = _stopWatch.Elapsed; string elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}", ts.Hours, ts.Minutes, ts.Seconds, ts.Milliseconds / 10); Console.WriteLine(elapsedTime, "RunTime"); } } private static void UsingStopWatchUsage() { Console.WriteLine("ConsoleAutoStopWatch Used: "); using (new ConsoleAutoStopWatch()) { Thread.Sleep(3000); } } 

两者都可能适合您的需求,但我会说使用StopWatch 。 为什么? 因为这意味着你正在做的任务。

你已经有了一个能够返回当前date/时间的类,它可以用来计时,而且你有一个专门用来计时的东西。

在这种情况下,如果你需要毫秒级的准确度(在这种情况下StopWatch更准确),这种差异才真正存在,但是作为一个普通的委托人,如果一个工具专门用于你正在寻找的任务,那么这是一个更好的方法。

我有一个小class来做这种特别的事情。 它使用秒表类 – c#微型性能testing 。

例如。

 var tester = new PerformanceTester(() => SomeMethod()); tester.MeasureExecTime(1000); Console.Writeline(string.Format("Executed in {0} milliseconds", tester.AverageTime.TotalMilliseconds)); 

使用下面的代码

 DateTime dExecutionTime; dExecutionTime = DateTime.Now; TimeSpan span = DateTime.Now.Subtract(dExecutionTime); lblExecutinTime.Text = "total time taken " + Math.Round(span.TotalMinutes,2) + " minutes . >>---> " + DateTime.Now.ToShortTimeString(); 

我把Hamish的回答简化了一下,使得它更通用一些,以防你需要login到其他地方:

 public class AutoStopWatch : Stopwatch, IDisposable { public AutoStopWatch() { Start(); } public virtual void Dispose() { Stop(); } } public class AutoStopWatchConsole : AutoStopWatch { private readonly string prefix; public AutoStopWatchConsole(string prefix = "") { this.prefix = prefix; } public override void Dispose() { base.Dispose(); string format = Elapsed.Days > 0 ? "{0} days " : ""; format += "{1:00}:{2:00}:{3:00}.{4:00}"; Console.WriteLine(prefix + " " + format.Format(Elapsed.Days, Elapsed.Hours, Elapsed.Minutes, Elapsed.Seconds, Elapsed.Milliseconds / 10)); } } private static void Usage() { Console.WriteLine("AutoStopWatch Used: "); using (var sw = new AutoStopWatch()) { Thread.Sleep(3000); Console.WriteLine(sw.Elapsed.ToString("h'h 'm'm 's's'")); } Console.WriteLine("AutoStopWatchConsole Used: "); using (var sw = new AutoStopWatchConsole()) { Thread.Sleep(3000); } }