C# DateTime.Now 是衡量函数性能的最佳方式吗?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/28637/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-03 08:17:34  来源:igfitidea点击:

Is DateTime.Now the best way to measure a function's performance?

提问by David Basarab

I need to find a bottleneck and need to accurately as possible measure time.

我需要找到瓶颈,需要尽可能准确地测量时间。

Is the following code snippet the best way to measure the performance?

以下代码片段是衡量性能的最佳方式吗?

DateTime startTime = DateTime.Now;

// Some execution process

DateTime endTime = DateTime.Now;
TimeSpan totalTimeTaken = endTime.Subtract(startTime);

采纳答案by Markus Olsson

No, it's not. Use the Stopwatch(in System.Diagnostics)

不,这不对。使用秒表(中System.Diagnostics

Stopwatch sw = Stopwatch.StartNew();
PerformWork();
sw.Stop();

Console.WriteLine("Time taken: {0}ms", sw.Elapsed.TotalMilliseconds);

Stopwatch automatically checks for the existence of high-precision timers.

秒表会自动检查高精度计时器的存在。

It is worth mentioning that DateTime.Nowoften is quite a bit slower than DateTime.UtcNowdue to the work that has to be done with timezones, DSTand such.

值得一提的是,由于时区、夏令时等必须完成的工作,这DateTime.Now通常要慢得多。DateTime.UtcNow

DateTime.UtcNow typically has a resolution of 15 ms. See John Chapman's blog postabout DateTime.Nowprecision for a great summary.

DateTime.UtcNow 通常具有 15 毫秒的分辨率。请参阅John Chapman 的关于DateTime.Now精确度的博文以获得很好的总结。

Interesting trivia: The stopwatch falls back on DateTime.UtcNowif your hardware doesn't support a high frequency counter. You can check to see if Stopwatch uses hardware to achieve high precision by looking at the static field Stopwatch.IsHighResolution.

有趣的琐事:DateTime.UtcNow如果您的硬件不支持高频计数器,秒表就会重新启动。您可以通过查看静态字段Stopwatch.IsHighResolution来检查 Stopwatch 是否使用硬件来实现高精度。

回答by jsight

The stopwatchfunctionality would be better (higher precision). I'd also recommend just downloading one of the popular profilers, though (DotTraceand ANTSare the ones I've used the most... the free trial for DotTrace is fully functional and doesn't nag like some of the others).

秒表功能会更好(精度更高)。不过,我还建议您只下载一种流行的分析器(DotTraceANTS是我使用最多的那些……DotTrace 的免费试用版功能齐全,不像其他一些分析器那样唠叨)。

回答by rp.

Use the System.Diagnostics.Stopwatch class.

使用 System.Diagnostics.Stopwatch 类。

Stopwatch sw = new Stopwatch();
sw.Start();

// Do some code.

sw.Stop();

// sw.ElapsedMilliseconds = the time your "do some code" took.

回答by Rob Cooper

I've done very little of this sort of performance checking (I tend to just think "this is slow, make it faster") so I have pretty much always gone with this.

我很少做这种性能检查(我倾向于认为“这很慢,让它更快”)所以我几乎总是这样做。

A google does reveal a lot of resources/articles for performance checking.

谷歌确实揭示了许多用于性能检查的资源/文章。

Many mention using pinvoke to get performance information. A lot of the materials I study only really mention using perfmon..

许多人提到使用 pinvoke 来获取性能信息。我研究的很多材料只真正提到使用 perfmon..

Edit:

编辑:

Seen the talks of StopWatch.. Nice! I have learned something :)

看到秒表的谈话..很好!我学到了一些东西:)

This looks like a good article

这篇文章看起来不错

回答by mmcdole

If you want something quick and dirty I would suggest using Stopwatch instead for a greater degree of precision.

如果你想要快速而肮脏的东西,我建议使用秒表来获得更高的精度。

Stopwatch sw = new Stopwatch();
sw.Start();
// Do Work
sw.Stop();

Console.WriteLine("Elapsed time: {0}", sw.Elapsed.TotalMilliseconds);

Alternatively, if you need something a little more sophisticated you should probably consider using a 3rd party profiler such as ANTS.

或者,如果您需要更复杂的东西,您可能应该考虑使用ANTS等 3rd 方分析器。

回答by Adam Haile

@Sean Chambers

@肖恩钱伯斯

FYI, the .NET Timer class is not for diagnostics, it generates events at a preset interval, like this (from MSDN):

仅供参考,.NET Timer 类不用于诊断,它以预设的时间间隔生成事件,如下所示(来自MSDN):

System.Timers.Timer aTimer;
public static void Main()
{
    // Create a timer with a ten second interval.
    aTimer = new System.Timers.Timer(10000);

    // Hook up the Elapsed event for the timer.
    aTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent);

    // Set the Interval to 2 seconds (2000 milliseconds).
    aTimer.Interval = 2000;
    aTimer.Enabled = true;

    Console.WriteLine("Press the Enter key to exit the program.");
    Console.ReadLine();
}

// Specify what you want to happen when the Elapsed event is 
// raised.
private static void OnTimedEvent(object source, ElapsedEventArgs e)
{
    Console.WriteLine("The Elapsed event was raised at {0}", e.SignalTime);
}

So this really doesn't help you know how long something took, just that a certain amount of time has passed.

所以这真的不能帮助你知道某件事花了多长时间,只是已经过去了一定的时间。

The timer is also exposed as a control in System.Windows.Forms... you can find it in your designer tool box in VS05/VS08

计时器也作为 System.Windows.Forms 中的控件公开...您可以在 VS05/VS08 的设计器工具箱中找到它

回答by Andrei R?nea

Ditto Stopwatch, it is way better.

同上秒表,它好多了。

Regarding performance measuring you should also check whether your "// Some Execution Process" is a very short process.

关于性能测量,您还应该检查您的“// Some Execution Process”是否是一个非常短的过程。

Also bear in mind that the first run of your "// Some Execution Process" might be way slower than subsequent runs.

还要记住,“// Some Execution Process”的第一次运行可能比后续运行慢。

I typically test a method by running it 1000 times or 1000000 times in a loop and I get much more accurate data than running it once.

我通常通过在循环中运行 1000 次或 1000000 次来测试方法,我得到的数据比运行一次更准确。

回答by Anthony Mastrean

It's useful to push your benchmarking code into a utility class/method. The StopWatchclass does not need to be Disposedor Stoppedon error. So, the simplest code to timesome actionis

将您的基准测试代码推送到实用程序类/方法中很有用。本StopWatch类并不需要是DisposedStopped出错。因此,为某些操作计时的最简单代码是

public partial class With
{
    public static long Benchmark(Action action)
    {
        var stopwatch = Stopwatch.StartNew();
        action();
        stopwatch.Stop();
        return stopwatch.ElapsedMilliseconds;
    }
}

Sample calling code

示例调用代码

public void Execute(Action action)
{
    var time = With.Benchmark(action);
    log.DebugFormat(“Did action in {0} ms.”, time);
}

Here is the extension method version

这是扩展方法版本

public static class Extensions
{
    public static long Benchmark(this Action action)
    {
        return With.Benchmark(action);
    }
}

And sample calling code

和示例调用代码

public void Execute(Action action)
{
    var time = action.Benchmark()
    log.DebugFormat(“Did action in {0} ms.”, time);
}

回答by OwenP

I just found a post in Vance Morrison's blog about a CodeTimer classhe wrote that makes using StopWatcheasier and does some neat stuff on the side.

我刚刚在 Vance Morrison 的博客中找到了一篇关于他编写的 CodeTimer 类的帖子,该类使使用StopWatch更容易,并且附带了一些整洁的东西。

回答by Iain

Visual Studio Team Systemhas some features that may help with this problem. Essentially you can write unit tests and mix them in different scenarios to run against your software as part of a stress or load test. This may help to identify areas of code that impact your applications performance the most.

Visual Studio Team System具有一些可能有助于解决此问题的功能。本质上,您可以编写单元测试并将它们混合在不同的场景中,以针对您的软件运行,作为压力或负载测试的一部分。这可能有助于识别对应用程序性能影响最大的代码区域。

Microsoft' Patterns and Practices group has some guidance in Visual Studio Team System Performance Testing Guidance.

Microsoft 的 Patterns and Practices 小组在Visual Studio Team System Performance Testing Guidance 中有一些指导。