我想衡量执行一件代码,我想知道最好的方法是什么?

选项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");

这不仅仅是用于基准测试,实际上它是应用程序的一部分。函数执行的时间是相关数据。但是,它不需要原子或超准确。

哪种选项更适合生产代码,或者其他人使用不同的东西,也许更好?

有帮助吗?

解决方案

Stopwatch 课程专门设计用于测量经过的时间,并且可以使用底层高频硬件计时器(如果在硬件上)(如果在硬件上)提供良好的粒度/准确性。因此,这似乎是最好的选择。

Ishighresolution属性 可用于确定是否可用的高分辨率正时。根据文档,该课程为“最佳可用” Win32 API提供了包装器,以进行准确的时机:

具体来说, Frequency 字段和 GetTimestamp 方法可以代替未托管的Win32 API QueryPerformanceFrequencyQueryPerformanceCounter.

关于那些Win32 API [此处]和链接的MSDN文档有详细的背景 2.

高分辨率计时器

计数器是用于编程中用于引用增量变量的一般术语。一些系统包括一个高分辨率性能计数器,可提供高分辨率经过的时间。

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

QueryPerformanceCounter 功能检索高分辨率性能计数器的当前值。通过在代码部分的开头和结尾调用此功能,应用程序本质上将计数器用作高分辨率计时器。例如,假设 查询性能频率 表明高分辨率性能计数器的频率为每秒50,000个计数。如果应用程序打电话 QueryPerformanceCounter 在要定时的代码部分之前和之后,计数器值可能分别为1500个计数和3500个计数。这些值表明在执行代码时,.04秒(2000个计数)经过。

其他提示

不只是那个 StopWatch 更准确,但也 DateTime.Now 在某些情况下会产生不正确的结果。

考虑在日光节省时间切换期间发生的情况,例如使用 DateTime.Now 实际上可以给 消极的 回答!

我通常使用 StopWatch 对于这种情况。

MSDN 页:

跑表

提供一组方法和属性,您可以使用这些方法和属性来准确测量经过的时间。

在以下文章中,我使用它比较Linq vs plinq的执行时间:

与Visual Studio 2010的平行LINQ(PLINQ)

这两个都不会损害表现,因为您说这不是那么重要。秒表似乎更合适 - 您只是从时间中减去时间,而不是另一个日期。日期的东西需要更多的内存和CPU时间来处理。如果您打算在多个地方重复使用,也有一些方法可以使代码清洁器进行清洁。超载 using 想到。我将搜索一个示例。好的,代码从:

http://stevesmithblog.com/blog/great-uses-us-us-usis-sus-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. 。为什么?因为它是为了完成您所做的任务。

您已经建立了一个课程来返回当前的日期/时间,因为它可以将其用于定时内容,并且您有一个专门设计用于计时的课程。

在这种情况下,只有在需要毫秒准确性的情况下才真正存在差异(在这种情况下 StopWatch 更准确),但是作为一般主体,如果某种工具专门用于您要寻找的任务,则可以使用更好的任务。

我有一个小课可以做这种事情。它使用秒表类 - C#微型灌注测试.

例如。

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的答案简化为简化,并使其更加通用,以防您需要登录到其他地方:

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

}
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top