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

如何衡量.NET中的代码性能?

如何解决《如何衡量.NET中的代码性能?》经验,为你挑选了4个好方法。

我正在使用DateTime对一行C#代码进行一些真正的快速和脏的基准测试:

long lStart = DateTime.Now.Ticks;
// do something
long lFinish = DateTime.Now.Ticks;

问题在于结果:

Start Time [633679466564559902]
Finish Time [633679466564559902]

Start Time [633679466564569917]
Finish Time [633679466564569917]

Start Time [633679466564579932]
Finish Time [633679466564579932]

...等等.

鉴于开始和结束时间相同,Ticks显然不够精细.

那么,我怎样才能更好地衡量绩效呢?



1> Noldorin..:

Stopwatch从.NET 2.0开始提供的这个类是最好的方法.它是一个非常高性能的计数器,精确到几毫秒.看看MSDN文档,这很清楚.

编辑:如前所述,建议多次运行代码以获得合理的平均时间.


您可以利用VS2015功能,在调试时看到2个断点之间经过的时间:http://blogs.msdn.com/b/visualstudioalm/archive/2015/07/20/performance-and-diagnostic-tools-in - 视觉工作室,2015.aspx

2> Joachim Saue..:

重复执行您的代码.问题似乎是您的代码执行速度比测量仪器的粒度快得多.对此最简单的解决方案是执行许多次(数千次,数百万次)代码,然后计算平均执行时间.

编辑:此外,由于当前优化编译器(以及CLR和JVM等虚拟机)的性质,测量单行代码的执行速度可能会非常误导,因为测量可能会对速度产生很大的影响.更好的方法是分析整个系统(或至少更大的块)并检查瓶颈在哪里.



3> Simon..:

我觉得这些很有用

http://accelero.codeplex.com/SourceControl/changeset/view/22633#290971 http://accelero.codeplex.com/SourceControl/changeset/view/22633#290973 http://accelero.codeplex.com/SourceControl/变更/视图/ 22633#290972

TickTimer是Stopwatch的缩减副本,在构建时启动并且不支持重新启动.如果当前硬件不支持高分辨率计时,它也会通知您(秒表吞下此问题)

所以这

var tickTimer = new TickTimer();
//call a method that takes some time
DoStuff();
tickTimer.Stop();
Debug.WriteLine("Elapsed HighResElapsedTicks " + tickTimer.HighResElapsedTicks);
Debug.WriteLine("Elapsed DateTimeElapsedTicks " + tickTimer.DateTimeElapsedTicks);
Debug.WriteLine("Elapsed ElapsedMilliseconds " + tickTimer.ElapsedMilliseconds);
Debug.WriteLine("Start Time " + new DateTime(tickTimer.DateTimeUtcStartTicks).ToLocalTime().ToLongTimeString());

会输出这个

Elapsed HighResElapsedTicks 10022886
Elapsed DateTimeElapsedTicks 41896
Elapsed ElapsedMilliseconds 4.18966178849554
Start Time 11:44:58

DebugTimer是TickTimer的包装器,它将结果写入Debug.(注意:它支持一次性模式)

所以这

using (new DebugTimer("DoStuff"))
{
    //call a method that takes some time
    DoStuff();
}

将它输出到调试窗口

DoStuff: Total 3.6299 ms

IterationDebugTimer用于计算多次运行操作并将结果写入Debug所需的时间.它还将执行未包含的初始运行,以忽略启动时间.(注意:它支持一次性模式)

所以这

int x;
using (var iterationDebugTimer = new IterationDebugTimer("Add", 100000))
{
    iterationDebugTimer.Run(() =>
    {
        x = 1+4;
    });
}

会输出这个

Add: Iterations 100000 
Total 1.198540 ms 
Single 0.000012 ms



4> Brian Rasmus..:

只是添加其他人已经说过的关于使用秒表和测量平均值的内容.

确保在测量前调用您的方法.否则,您将测量JIT编译代码所需的时间.这可能会显着扭曲您的数字.

此外,请确保测量发布模式代码,因为默认情况下调试版本的优化已关闭.调整调试代码是毫无意义的.

并确保您正在测量您实际想要测量的内容.当优化启动时,编译器/ JIT编译器可能会重新排列代码或将其完全删除,因此您最终可能会测量与预期稍有不同的内容.至少看看生成的代码,以确保代码没有被剥离.

根据您要测量的内容,请注意,真实系统会比典型的测试应用程序更不同于运行时.一些性能问题与例如垃圾收集对象有关.这些问题通常不会出现在简单的测试应用程序中.

实际上,最好的建议是使用真实数据来测量真实系统,因为沙箱测试可能会变得非常不准确.

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