当前位置:  开发笔记 > 编程语言 > 正文

是DateTime.Now是测量函数性能的最佳方法吗?

如何解决《是DateTime.Now是测量函数性能的最佳方法吗?》经验,为你挑选了13个好方法。

我需要找到一个瓶颈,并且需要准确地测量时间.

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

DateTime startTime = DateTime.Now;

// Some execution process

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

Markus Olsso.. 642

不,这不对.使用秒表(in System.Diagnostics)

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

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

秒表会自动检查是否存在高精度计时器.

值得一提的是,由于必须使用时区,DST等进行的工作,DateTime.Now通常要慢得多.DateTime.UtcNow

DateTime.UtcNow通常具有15毫秒的分辨率.请参阅John Chapman关于DateTime.Now精确度的博客文章,以获得精彩的摘要.

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



1> Markus Olsso..:

不,这不对.使用秒表(in System.Diagnostics)

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

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

秒表会自动检查是否存在高精度计时器.

值得一提的是,由于必须使用时区,DST等进行的工作,DateTime.Now通常要慢得多.DateTime.UtcNow

DateTime.UtcNow通常具有15毫秒的分辨率.请参阅John Chapman关于DateTime.Now精确度的博客文章,以获得精彩的摘要.

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


我放置了一个PerformWork(); 在秒表之前"加热".
还必须添加建议,如果您的`PerformWork()`非常短,您可以重复调用它并计算一批调用的平均值.此外,计算整批电话的时间,而不是启动/停止你的"秒表"以避免频闪效应,这会影响您的定时测量.
@Pavel,很明显,Microsoft推荐使用秒表作为运行Windows 7和Windows 8的现代多核处理器的最佳解决方案(低开销和高精度).https://msdn.microsoft.com/en-us/库/窗/台式机/ dn553408%28V = vs.85%29.aspx

2> mmcdole..:

如果你想要快速和肮脏的东西,我会建议使用秒表,以获得更高的精确度.

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

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

或者,如果您需要更复杂的东西,您应该考虑使用第三方分析器,例如ANTS.



3> Valentin Kuz..:

这篇文章说,首先你需要比较三种选择Stopwatch,DateTime.NowAND DateTime.UtcNow.

它还显示在某些情况下(当性能计数器不存在时)秒表正在使用DateTime.UtcNow +一些额外的处理.因为很明显,在这种情况下,DateTime.UtcNow是最好的选择(因为其他使用它+一些处理)

然而,事实证明,计数器几乎总是存在 - 请参阅有关高分辨率性能计数器及其与.NET秒表相关的解释?.

这是一个性能图表.请注意UtcNow与替代品相比性能成本如何低:

在此输入图像描述

X轴是样本数据大小,Y轴是示例的相对时间.

有一点Stopwatch是更好的是它提供更高分辨率的时间测量.另一个是它更具OO性质.但是,创建一个OO包装器UtcNow并不难.



4> Anthony Mast..:

将基准测试代码推送到实用程序类/方法中非常有用.本StopWatch类并不需要是DisposedStopped出错.所以,最简单的代码有些动作

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

样本调用代码

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

这是扩展方法版本

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

并调用代码示例

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



5> jsight..:

该秒表功能会更好(精度更高).我也建议只下载一个流行的分析器,但是(DotTrace和ANTS是我最常用的...... DotTrace的免费试用功能完全正常,并不像其他一些人那样唠叨).



6> rp...:

使用System.Diagnostics.Stopwatch类.

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

// Do some code.

sw.Stop();

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



7> Andrei Rînea..:

Ditto秒表,它的方式更好.

关于绩效衡量,您还应该检查您的"//一些执行流程"是否是一个非常短的过程.

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

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



8> Mike Dunlave..:

这些都是衡量时间的好方法,但这只是找到瓶颈的一种非常间接的方式.

在线程中找到瓶颈的最直接方法是让它运行,当它正在做任何让你等待的事情时,用暂停或中断键停止它.这样做几次.如果您的瓶颈占用X%的时间,则X%是您在每个快照的行为中捕获它的概率.

以下是对其工作原理和原因的更完整解释



9> Adam Haile..:

@ 肖恩钱伯斯

仅供参考,.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);
}

所以这真的无法帮助你知道事情花了多长时间,只是已经过了一段时间.

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



10> Iain..:

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

Microsoft的模式和实践组在Visual Studio Team System性能测试指南中有一些指导.



11> 小智..:

这是正确的方法:

using System;
using System.Diagnostics;

class Program
{
    public static void Main()
    {
        Stopwatch stopWatch = Stopwatch.StartNew();

            // some other code

        stopWatch.Stop();

        // this not correct to get full timer resolution
        Console.WriteLine("{0} ms", stopWatch.ElapsedMilliseconds);

        // Correct way to get accurate high precision timing
        Console.WriteLine("{0} ms", stopWatch.Elapsed.TotalMilliseconds);
    }
}

有关更多信息,请使用Stopwatch而不是DataTime来获取准确的性能计数器.



12> OwenP..:

我刚刚在Vance Morrison的博客中发现了一篇关于他编写的CodeTimer课程的帖子,该课程使得使用StopWatch更容易并且做了一些整洁的东西.



13> 小智..:

这还不够专业:

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

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

一个更可靠的版本是:

PerformWork();

int repeat = 1000;

Stopwatch sw = Stopwatch.StartNew();
for (int i = 0; i < repeat; i++)
{
   PerformWork();
}

sw.Stop();

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

在我的真实代码中,我将添加GC.Collect调用以将托管堆更改为已知状态,并添加Sleep调用,以便可以在ETW配置文件中轻松分隔不同的代码间隔。

推荐阅读
手机用户2402852387
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有