我正在尝试调整我的应用程序的性能。而且我很好奇哪些方法处理时间最长,因此应该查看任何优化机会。
是否有任何现有的免费工具可以帮助我可视化调用堆栈以及每个方法需要多长时间才能完成?我正在考虑将调用堆栈显示为堆积条形图或树形图的东西,因此很容易看出MethodA()需要 10 秒才能完成,因为它调用MethodB()和Method(C)需要 3 和 7 秒才能完成完全的。
这样的事情存在吗?
我正在尝试调整我的应用程序的性能。而且我很好奇哪些方法处理时间最长,因此应该查看任何优化机会。
是否有任何现有的免费工具可以帮助我可视化调用堆栈以及每个方法需要多长时间才能完成?我正在考虑将调用堆栈显示为堆积条形图或树形图的东西,因此很容易看出MethodA()需要 10 秒才能完成,因为它调用MethodB()和Method(C)需要 3 和 7 秒才能完成完全的。
这样的事情存在吗?
是的,它们被称为性能分析器。查看 RedGate ANTS 和 JetBrains 的 dotTrace,不是免费的,但非常便宜,而且比我见过的任何免费替代品都好。
测量的方式是通过仪器或分析器内的采样。
Instrumentation 大致相当于重写所有代码以执行以下操作:
public void Foo()
{
//Code
}
进入
public void Foo()
{
InformTheProfilingCodeThatFooStarted();
//Code
InformTheProfilingCodeThatFooEnded();
}
由于分析器知道一切何时开始和停止,它可以管理堆栈何时开始和停止,并在以后提供此信息。许多允许您在行级别执行此操作(通过做很多相同的事情,但在每行之前进行更多检测。
这会在应用程序中的“调用图”上获得 100% 准确的信息,但这样做的代价是:防止方法内联并为每个方法调用增加相当大的开销。
另一种方法是抽样。
这种方法不是试图获得 100% 准确的调用图,但实际时间不准确时间它在各种功能中,而实际上不必花费很多精力来解决这个问题。大多数采样分析器都知道如何在中断程序时“解析”调用堆栈,因此他们仍然可以合理地了解什么正在调用哪个函数以及这似乎需要多少时间,但无法告诉您这是否是(比如说)对 Foo() 的 10 次调用,对 Bar() 进行了 10 次调用,或者对 Foo() 的一次调用在对 Bar() 的一次调用中,它恰好持续了这么长时间,它被采样了 10 次。
两种方法各有利弊,解决的问题也不同。一般来说,采样方法是最好的方法,因为它侵入性较小,因此应该提供更准确的信息,说明什么需要时间,这通常是找出原因之前最重要的第一个问题。
我只知道一个用于 .net 代码的免费采样分析器,它是与 VS 2008 Team System 版本相关联的免费可再发行分析器(但可以单独下载)。除了(非常昂贵的)Visual Studio Team System 版本之外,无法轻松查看生成的输出。
Red Gate ANTS 不支持采样(目前),Jet Brains (dotTrace) 和 MS Visual Studio Team System 具有支持这两种样式的分析器。您更喜欢在成本效益的基础上是一个意见问题。
这是我使用的方法。如果您有一个带有暂停按钮的 IDE,它不会花费任何成本并且运行良好。
它告诉您的大致是每个例程中花费的挂钟时间的百分比,更准确地说,是在每个语句中。这比执行例程或语句的平均持续时间更重要,因为它会自动考虑调用计数。通过对挂钟时间进行采样,它会自动包含 CPU、IO 和其他类型的系统时间。
更重要的是,如果您查看您的例程在调用堆栈中的示例,您不仅可以看到它在做什么,还可以看到为什么。重要的原因是您真正要寻找的是可以用更快的东西代替的时间。如果没有“为什么”信息,您必须猜测那是什么。
顺便说一句:这种技术鲜为人知,主要是因为教授不教它(即使他们知道),因为他们很少需要像我们在现实世界中那样使用可怕的软件,所以他们将gprof
其视为分析的基础范式。
PS 预计百分比加起来会超过 100%。考虑百分比的方法是,如果语句或例程有 X% 的时间在堆栈上(根据少量样本估计),那么如果该语句或例程大致上会缩短多少挂钟时间可以减少很多时间。
有几个分析器可用。我只熟悉一个(Visual Studio Team Suite 中包含的那个),但它不是免费的。我必须说,它足够强大/可靠,以至于我不想尝试切换到另一个。我听说的另一个是 Red Gate 的 .NET profiler(也不是免费的)。这两者都有功能集,包括但绝对不限于您所追求的。如果这是用于商业应用程序开发,请务必查看它们。:)