测量 C# 中的执行时间

发布于 2024-09-27 05:45:03 字数 942 浏览 1 评论 0原文

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

选项 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: 使用系统诊断;

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

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

哪个选项对于生产代码更好,或者其他人是否使用不同的或者更好的东西?

I want to measure the execution of a piece of code and I'm wondering what the best method to do this is?

Option 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");

Option 2:
using 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");

This isn't simply for benchmarking, its actually part of the application. The time the function takes to execute is relevant data. It doesn't however need to be atomic or hyper-accurate.

Which option is better for production code, or does anybody else use something different and perhaps better?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

诗化ㄋ丶相逢 2024-10-04 05:45:03

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

IsHighResolution 属性可用于确定是否提供高分辨率计时。根据文档,此类提供了“最佳可用”Win32 API 的包装器,以实现准确计时:

具体来说,Frequency 字段和
GetTimestamp 方法可用于
非托管 Win32 API 的位置
QueryPerformanceFrequency
查询性能计数器

有关这些 Win32 API 的详细背景信息 [此处] 和链接的 MSDN 文档 2

高分辨率计时器

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

如果高分辨率表现
系统上存在计数器,您可以
使用QueryPerformanceFrequency
表示频率的函数,用
每秒计数。的价值
计数取决于处理器。在一些
处理器,例如计数
可能是循环率
处理器时钟。

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

The Stopwatch class is specifically designed to measure elapsed time and may (if available on your hardware) provide good granularity/accuracy using an underlying high-frequency hardware timer. So this seem the best choice.

The IsHighResolution property can be used to determine whether high resolution timing is available. Per the documentation, this class offers a wrapper on the 'best available' Win32 APIs for accurate timing:

Specifically, the Frequency field and
GetTimestamp method can be used in
place of the unmanaged Win32 APIs
QueryPerformanceFrequency and
QueryPerformanceCounter.

There is detailed background on those Win32 APIs [here] and in linked MSDN docs 2.

High-Resolution Timer

A counter is a general term used in
programming to refer to an
incrementing variable. Some systems
include a high-resolution performance
counter that provides high-resolution
elapsed times.

If a high-resolution performance
counter exists on the system, you can
use the QueryPerformanceFrequency
function to express the frequency, in
counts per second. The value of the
count is processor dependent. On some
processors, for example, the count
might be the cycle rate of the
processor clock.

The QueryPerformanceCounter function
retrieves the current value of the
high-resolution performance counter.
By calling this function at the
beginning and end of a section of
code, an application essentially uses
the counter as a high-resolution
timer. For example, suppose that
QueryPerformanceFrequency indicates
that the frequency of the
high-resolution performance counter is
50,000 counts per second. If the
application calls
QueryPerformanceCounter immediately
before and immediately after the
section of code to be timed, the
counter values might be 1500 counts
and 3500 counts, respectively. These
values would indicate that .04 seconds
(2000 counts) elapsed while the code
executed.

以往的大感动 2024-10-04 05:45:03

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

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

It's not just that StopWatch is more accurate, but also that DateTime.Now will give incorrect results in some circumstances.

Consider what happens during a daylight saving time switch-over, for example — using DateTime.Now can actually give a negative answer!

若能看破又如何 2024-10-04 05:45:03

对于这种情况,我通常使用秒表。

来自 MSDN 页面:

秒表

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

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

使用 Visual Studio 2010 的并行 LINQ (PLINQ)

I generally use StopWatch for this kind of situation.

From MSDN page:

StopWatch

Provides a set of methods and
properties that you can use to
accurately measure elapsed time.

In the following post I use it to compare the execution time of LINQ vs PLINQ:

Parallel LINQ (PLINQ) with Visual Studio 2010

乖不如嘢 2024-10-04 05:45:03

两者都不会损害性能,因为你说它并不那么重要。秒表似乎更合适 - 您只是从时间中减去时间,而不是从一个日期减去另一个日期。日期内容需要更多的内存和 CPU 时间来处理。如果您打算在多个地方重用代码,还有一些方法可以使代码更简洁。我想到了重载using。我会寻找一个例子。好的,代码窃取自:

http://stevesmithblog.com/博客/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);
    }
}

Neither will hurt the performance, because you say it is not that critical. StopWatch seems more appropriate - you are only subtracting time from time and not one date from another. Date stuff takes a tad more memory and CPU time to deal with. There are also ways to make the code cleaner, in case you plan on reusing it in several places. Overloading using comes to mind. I will search for an example. Ok, code stolen from:

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);
    }
}
没有伤那来痛 2024-10-04 05:45:03

两者都可能很好地满足您的需求,但我建议使用 StopWatch。为什么?因为它是为了你正在做的任务而设计的。

您有一个类是为返回当前日期/时间而构建的,它恰好可以用于计时,并且您有一个专门为计时而设计的类。

在这种情况下,只有当您需要毫秒精度时,差异才真正存在(在这种情况下,StopWatch 更准确),但作为一般原则,如果存在专门用于您正在寻找的任务的工具,那么它就是越用越好。

Both will likely fit your needs just fine, but I would say use StopWatch. Why? Cause it's meant for the task you're doing.

You've got one class that's built to return the current date/time, which as it happens can be used for timing things, and you've got one class specifically designed for timing things.

In this case the differences only really exist if you need millisecond accuracy (In which case StopWatch is more accurate), but as a general principal if a tool exists specifically for the task you're looking for then it's the better one to use.

美胚控场 2024-10-04 05:45:03

我有一个小班专门做这类事情。它使用秒表类 - c# 微性能测试

例如。

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

I have a little class to do this sort of thing ad hoc. It uses the stopwatch class - c# micro perfomance testing.

eg.

var tester = new PerformanceTester(() => SomeMethod());
tester.MeasureExecTime(1000);
Console.Writeline(string.Format("Executed in {0} milliseconds", tester.AverageTime.TotalMilliseconds));
残花月 2024-10-04 05:45:03

使用下面的代码

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

Use below code

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();
浅笑轻吟梦一曲 2024-10-04 05:45:03

我采用哈米什的答案简化了它,并使其更加通用,以防您需要登录到其他地方:

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

}

I took Hamish's answer simplified it and made it a bit more general in case you need to log to somewhere else:

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

}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文