似乎没有免费的* .NET性能分析器可以逐行进行分析。因此,我正在研究使用秒表进行性能分析。
*自由免费,即许可包括商业申请。
编辑:回应那些告诉我“买个探路者”的人,我想,但如果我可以花那么多钱,我就会把钱花在别的东西上。我试图说服我的老板说一个分析器值得,但运气不好。这个问题主要基于好奇心。我永远不会认为秒表可以替代真实的探测器。我有一个小测试应用程序(用C#编写),用于衡量在每行使用秒表时的性能差异。测试代码是这样的:
int n = 100;
BigInteger f = 1;
for (int i = n; i > 1; i--)
{
f *= i;
}
以下是完整代码:http://pastebin.com/AvbQmT32
每行代码都有一个秒表。这是我的“探查者”。我整个节目也有一个秒表。这是我的'profiler profiler'。
我将程序配置为发布模式,任何CPU(在x64计算机上),并禁用优化。
当我在禁用探查器的情况下运行程序时,我会得到类似的结果:
Line | Ticks
------------------------------|----------
|
Total time: | 359
当我在启用了探查器的情况下运行它时,我会得到这样的结果:
Line | Ticks
------------------------------|----------
|
int n = 100; | 3
BigInteger f = 1; | 12
for (int i = n; i > 1; i--) | 325
{ |
f *= i; | 539
} |
|
Total time: | 1710
Stopwatch overhead: | 831
理想情况下,在两种情况下花在代码上的时间应该相等,但看起来Stopwatches的开销会出现在自己经过的时间内。
现在,需要对程序的每一行进行分析通常没有意义,因为通常采用分而治之的方法可以更好地工作。您通常可以从分析代码块开始,并缩小任何性能问题。
此外,在大多数应用程序中,平均代码行将比测试程序中的代码慢很多。这意味着秒表开销会减少。
但是,使用Stopwatches时仍然存在开销,特别是如果你经常使用。
所以问题是:
使用Stopwatches进行性能分析的最有效方法是什么?如何最大限度地减少开销?围绕一个声明包装秒表是否值得?
感谢您的反馈意见。
答案 0 :(得分:4)
考虑到我们经常通过Single responsibility principle直观地编程,不仅在类型方面而且在函数方面,我会说没有任何分析应用程序逐行。您将更感兴趣的是分析一个单一的责任"然后每一行。
当然,当你需要来获取信息时也是如此。但是不要在所有应用程序中使用它,而是在函数的单个部分或单个函数中使用它。在这种情况下,StopWatch
是最佳选择。请注意StopWatch
是.NET Class
,因此 它甚至是最小的开销。您不应该查看绝对,而应该查看相对值。
希望这有帮助。
答案 1 :(得分:2)
你不应该看到确切的数字,你应该寻找相对的差异。这样您就可以识别问题区域。您正在寻找可以解决性能问题的优化场所。
如果您正在开发性能实际上是问题的级别的代码,并且您需要对其进行分析以找到有问题的代码,那么购买一个工具来为您执行此任务将不仅仅是在节省的时间内收回成本。我推荐使用Visual Studio Premium附带的分析器。
答案 2 :(得分:2)
您是否尝试过查看CInject:http://codeinject.codeplex.com/documentation?它基本上将代码注入DLL。开箱即用它似乎有性能监控,但它也允许您创建自己的代码注入。似乎非常适合您尝试做的事情。
答案 3 :(得分:2)
第一件事:你的结果并不令人惊讶。如果你使用的是商业分析器,你会看到类似的东西:你的程序在被分析时需要花费更长的时间才能运行。您设置分析器的粒度越精细,您可以预期的时间就越长。当你考虑像" i>这样的陈述时1"和"我 - "可能会作为单处理器指令执行,很明显为什么分析特定行的执行时间比执行行本身要花费更长的时间。
分析正在增加程序的整体运行时间这一事实不应该成为一个问题;正如其他几个人所提到的那样,重要的不是程序运行的绝对时间,而是将各个部分的运行时间相互比较以找出瓶颈。但还有另一个问题。秒表将使用底层操作系统中的高频计时器(如果有的话);但即使这可能还不够高。我的Windows 7 64位i5-2400(四核3.10 GHz)上的高频定时器每秒发送3,020,556次。听起来很多;但按照这个速度,处理器可以在刻度线之间执行一千条指令。这意味着如果您正在尝试测量执行单个指令所需的时间,那么您将要么处于低位状态,要么会出现超调状态。
您最好在方法级别进行性能分析。即使这样,你也会遇到频率问题,特别是如果你有一些精心设计的方法。但结果将比在线级别更可靠;一旦您确定了导致瓶颈的方法,您可以直接检查它以确定如何优化它以更好地执行。
所有这些都抛弃了一般性能分析的许多警告,这超出了本文的范围。确保您对该主题进行额外的研究,以了解您应该如何解释您获得的结果。作为一个简单的例子,您的分析可能会揭示程序中的大部分时间都花在特定方法上;但这是否意味着方法本身就是问题,或者其他方法经常调用它?回答这类问题是分析中真正困难的地方。
答案 4 :(得分:1)
您是否将没有分析器的总时间与分析器在调试模式下的时间进行了比较?我的第一个猜测是额外的时间出现,因为秒表的额外声明阻止了一些寄存器或循环优化。因此,额外的时间可能来自缺失的优化,而不是秒表内部的时间损失。
然而,话虽如此,即使秒表具有高分辨率,我认为你会注意到一些时间误差测量的东西只有一行代码。例如'int n = 100'是汇编中的一行,因此在技术术语中我认为它只有1个刻度。从运行到运行,您在数字中注意到多少变化?如果您得到的变化占平均值的很大一部分,那么该值实际上并没有给您太多信息。
答案 5 :(得分:0)
也许你应该考虑分析方法的调用时间,而不是单行。毕竟,方法调用通常是调用代码中的单行。另一个有趣的方法是使用日志库来记录方法输入和退出,例如,像这样(使用log4net作为选择的记录器):
public string MyMethod(string arg)
{
string result = null;
if (logger.IsDebugEnabled) logger.Debug("->MyMethod(" + arg + ")");
// do stuff
result = "Hello world!";
if (logger.IsDebugEnabled) logger.Debug("<-MyMethod(" + arg + ") = " + result);
return result;
}
这将创建一个日志文件,该文件对于查看应用程序正在执行的操作非常有用,并且它可以为写入日志的每一行添加时间戳,因此您可以查看特定方法是否需要很长时间。使用log4net,您可以轻松更改配置以关闭注销,因此当您不需要它时,您不会支付任何性能损失。
答案 6 :(得分:0)
如果您有Visual Studio Ultimate,请尝试使用Visual Studio Profiler。这很不错。