我有这个.NET应用程序,它依赖于延迟执行。当我分析它时,消耗大部分时间的方法是那些枚举IEnumerables的方法。因此我认为必须优化的方法不在Top Time Consuming方法中。
是不是发生在你身上?如何在这种情况下正确分析应用程序?答案 0 :(得分:1)
Jader,如果您可以在IDE下运行应用程序并随机暂停,那么有一种非正统但非常快速有效的方法可以找出负责的时间。有些人知道,我试图详细解释。 Here's my latest attempt.祝你好运。 Here's another explanation和an example。
补充:在你的评论中,你说这就是采样分析器所做的,只是更快。即使他们实际上对整个调用堆栈进行采样,也存在两个大问题:
他们总结,通常是在函数或方法层面,这意味着您必须在耗时的函数中寻找耗时的语句。当您搜索该信息时,堆栈样本实际上拥有它,但没有显示给您。理由是有太多的样本供你查看,所以他们必须总结一下。但是,如果某些语句在调用堆栈上有百分之一的时间,例如50%(并非罕见),那么这正是删除它所保存的内容,而这大约是包含它的样本的百分比。十个样本肯定会显示为1000,因此浪费了额外的样本,并且包含其信息的努力只会导致混淆。一些分析人员总结了陈述的水平,这是一种改进,但它遇到了第二个问题:
您需要知道 执行耗时代码的原因,并且不会向您显示该信息。堆栈示例中的信息。如果语句在某些部分样本的调用堆栈上,请查看其中一个或多个样本。调用堆栈为您提供了执行语句的理由链。既然你知道为什么要这样做,你可以判断是否有另一种方法可以完成同样的事情而不需要花费太多时间,比如使用先前调用该语句的缓存数据。有些分析器会给你一个调用树或一个调用图,但这些都是摘要,这意味着你仍然需要弄清楚为什么语句在很多时候被调用。
我希望这可以让你了解我正在驾驶的东西。您必须聚合和测量以便定位问题的一般想法是很自然的,但提取少量信息样本中包含的完整信息会更有效。
P.S。不要认为递归是一个问题。递归表示为在某些样本中出现不止一次的语句。仍然是包含该陈述的样本的分数是其成本的估计。 (您可能想要考虑一下。)
关于该技术还有其他常见的误解(例如它只针对小型程序),这些误解在上面的链接中进行了探讨。
答案 1 :(得分:0)
在如下所示的简单应用程序中,对其进行分析并不困难。但在更复杂的应用程序中,我找不到延迟的原因。
以下计划:
static IEnumerable<int> TimeConsuming()
{
foreach (var i in Enumerable.Range(0, 10000))
{
Thread.Sleep(1);
yield return i;
}
}
static void Enumerates(IEnumerable<int> enumerable)
{
enumerable.ToArray();
}
static void Main(string[] args)
{
var enumerable = TimeConsuming();
Enumerates(enumerable);
}
当检测仪器显示正确的延迟原因时:
Function Name Inclusive Time % ConsoleApplication1.Program.Main(string[]) 99.60 ConsoleApplication1.Program.<TimeConsuming>d__0.MoveNext() 99.89