当延迟执行变得困难时如何分析应用程序?
我有这个 .NET 应用程序,它依赖于延迟执行。当我对其进行分析时,消耗最多时间的方法是枚举 IEnumerables 的方法。因此,我认为必须优化的方法并不属于最耗时的方法。
你有发生过这种事吗?在这种情况下如何正确分析应用程序?
I have this .NET application, which relies on deferred execution. When I am profiling it the methods that consume most time are those who enumerates the IEnumerables. Because of this I think that the methods that must be optimized are not in the Top Time Consuming methods.
Did it ever happened to you? How to profile an application correctly in this situation?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
Jader,如果您可以在 IDE 下运行该应用程序并随机暂停它,那么有一种非正统但非常快速且有效的方法可以找出导致该时间的原因。有几个人知道这一点,我试图详细解释一下。 这是我的最新尝试。祝你好运。 这是另一个解释和示例。
添加:在您的评论中,您说这正是采样分析器所做的,只是速度更快。即使他们实际上对整个调用堆栈进行了采样,也存在两个大问题:
他们总结,通常是在函数或方法级别,这意味着您必须在耗时的函数内部寻找找到耗时的语句。当您寻找该信息时,堆栈示例实际上拥有该信息,但没有向您显示。理由是样本太多你看不下去,所以他们必须总结一下。但是,如果某个语句在一定百分比的时间内位于调用堆栈上,例如 50%(并不罕见),那么这正是通过删除它而保存的内容,并且这大约是包含它的样本的百分比。 10 个样本与 1000 个样本一样可以肯定地显示它,因此额外的样本被浪费了,而包含其信息的努力只会导致混淆。一些分析器在语句级别进行总结,这是一种改进,但它会遇到第二个问题:
您需要知道原因时间-正在执行使用代码,并且该信息不会向您显示。 信息就在那里,在堆栈示例中。如果某个语句位于部分样本的调用堆栈上,则只需查看其中一个或多个样本即可。调用堆栈为您提供了执行该语句的原因链。由于您知道为什么要这样做,因此您可以判断是否有另一种方法可以完成同样的事情,并且不需要花费太多时间,例如使用先前调用该语句的缓存数据。一些探查器为您提供调用树或调用图,但这些只是摘要,这意味着您仍然必须弄清楚为什么该语句被如此频繁地调用。
我希望这能让您了解我的目的。必须聚合和测量才能定位问题的一般想法是很自然的,但提取少量信息样本中包含的完整信息要有效得多。
PS 不要认为递归是一个问题。递归表现为在某些示例中多次出现的语句。包含该声明的样本比例仍然是对其成本的估计。 (您可能需要考虑一下。)
有关该技术的其他常见误解(例如它仅适用于小型程序),请在上面的链接中进行探讨。
Jader, if you can run the app under an IDE and pause it at random, there is an unorthodox but very quick and effective way to find out what is responsible for the time. A few people know it, and I've tried to explain it at length. Here's my latest attempt. Good luck. Here's another explanation and an example.
ADDED: In your comment, you said that is just what sampling profilers do, only faster. Even if they actually sample the entire call stack, there are two big problems:
They summarize, often at the level of functions or methods, meaning that you have to hunt inside time-consuming functions to find the time-consuming statements. While you are hunting for that information, the stack samples actually have it but didn't show it to you. The rationale is that there are too many samples for you to look at, so they have to summarize. However, if some statement is on the call stack some percent of the time, like 50% (not unusual), then that is exactly what would be saved by its removal, and that is roughly the percent of samples that contain it. Ten samples would show it just as surely as 1000, so the extra samples are wasted, and the effort to include their information just causes obfuscation. Some profilers summarize at the level of statements, and that is an improvement, but it runs into the second issue:
You need to know the reason why the time-consuming code is being executed, and that information is not shown to you. The information is there, in the stack samples. If a statement is on the call stack on some fraction of the samples, just look at one or more of those samples. The call stack gives you the chain of justification of why the statement is being executed. Since you know why it's being done, you can tell if there is another way to accomplish the same thing that does not take so much time, such as using cached data from a prior invocation of that statement. Some profilers give you a call tree or a call graph, but those are summaries meaning you still have to puzzle out exactly why the statement is being called so much of the time.
I hope this gives you a sense of what I'm driving at. The general idea that you have to aggregate and measure in order to locate problems is a natural one, but it is far more effective to extract the full information contained in a small number of informative samples.
P.S. Don't think that recursion is an issue. Recursion manifests as a statement appearing more than once in some samples. It is still the case that the fraction of samples containing the statement is an estimate of its cost. (You might want to think about that for a minute.)
There are other common misconceptions about the technique (such as its only working on small programs), that are explored in the links above.
在像下面这样的简单应用程序中,对其进行分析并不困难。但在更复杂的应用程序中我还找不到延迟的原因。
以下程序:
当分析的仪器显示延迟的正确原因时:
In a simple application like the one below it's not so difficult to profile it. But in more complex applications I couldn't find the cause of delay yet.
The following program:
When instrumentation profiled shows the correct cause of delay: