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

时间:2020-03-05 18:43:26  来源:igfitidea点击:

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

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

DateTime startTime = DateTime.Now;

// Some execution process

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

解决方案

回答

秒表功能会更好(精度更高)。不过,我也建议我们下载其中一个最受欢迎的分析器(DotTrace和ANTS是我使用最多的分析器... DotTrace的免费试用版功能齐全,与其他一些产品并不相称)。

回答

不,这不对。使用秒表(位于" 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通常具有15ms的分辨率。有关出色的总结,请参见John Chapman的有关" DateTime.Now"精度的博客文章。

有趣的琐事:如果硬件不支持高频计数器,则秒表将退回到DateTime.UtcNow上。我们可以通过查看静态字段Stopwatch.IsHighResolution来检查Stopwatch是否使用硬件来实现高精度。

回答

使用System.Diagnostics.Stopwatch类。

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

// Do some code.

sw.Stop();

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

回答

我很少进行这种性能检查(我倾向于只是认为"这很慢,要使其更快"),所以我几乎总是这样做。

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

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

编辑:

看过秒表的话题..太好了!我学到了一些东西:)

这看起来像是一篇好文章

回答

如果我们想要快速又脏的东西,我建议我们改用秒表,以获得更高的精度。

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

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

另外,如果我们需要更高级的工具,则可能应该考虑使用ANTS这样的第三方分析器。

回答

@塞恩·钱伯斯

仅供参考,.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的设计器工具框中找到它

回答

同上秒表,这是更好的方法。

关于性能评估,我们还应该检查" //某些执行过程"是否是很短的过程。

还请记住," //某些执行过程"的第一次运行可能比随后的运行慢。

我通常通过在一个循环中运行1000次或者1000000次来测试一种方法,并且得到的数据比运行一次要准确得多。

回答

将基准测试代码推送到实用程序类/方法中很有用。无需在发生错误时将" StopWatch"类丢弃或者"停止"。因此,计时某些动作的最简单代码是

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

回答

我刚刚在Vance Morrison的博客中找到一篇有关他编写的CodeTimer类的文章,该类使使用StopWatch更容易,并且在侧面做了一些整洁的事情。

回答

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

Microsoft的Patterns and Practices组在Visual Studio Team System性能测试指南中提供了一些指南。

回答

这些都是衡量时间的好方法,但这只是发现瓶颈的一种非常间接的方法。

在线程中查找瓶颈的最直接方法是使其运行,并且在执行任何使我们等待的事情时,请使用暂停键或者Break键将其暂停。这样做几次。如果瓶颈花费了X%的时间,则X%是我们在每个快照的动作中捕获它的概率。

这是有关其运作方式和运作方式的更完整说明