【发布时间】:2011-04-12 16:06:41
【问题描述】:
【问题讨论】:
-
您的程序总体上在做什么?用户界面是否在做一些奇怪的事情,你是否注意到使用它时速度很慢?
标签: c# winforms performance profiling red-gate-ants
【问题讨论】:
标签: c# winforms performance profiling red-gate-ants
你无法解决这个问题。
框架正在调用由 Windows API 公开的 DispatchMessage function,该 API 用于将通过调用 GetMessage 函数检索到的消息发送到特定窗口的窗口过程。
这里的“慢”部分是 Windows 本身。当这成为您的瓶颈时,您的应用程序已充分优化,您无能为力。
此外,这些配置文件结果不一定告诉您此功能慢。相反,他们告诉你它被调用很多(“命中计数”)。这个想法是,经常被调用的函数是代码中的“热点”,值得花一些额外的时间来优化它们的实现(更划算)。但是,在这种情况下,该函数会被大量调用,因为它是 Windows 为您的应用程序处理消息的方式。在非托管代码和本机 Windows API 的世界中,消息有点像您在 .NET 代码中使用的事件。由于任何有趣的事情都必须引发事件,因此负责调用或分派这些事件(消息)的函数必然会被调用很多次。
【讨论】:
Windows 应用程序通常包含一个顶级循环,它们在其中等待鼠标移动/点击和键盘敲击等外部事件或内部生成的事件。当一个事件发生时,它会调用适当的处理程序,这可能会做一些事情,也可能做很多事情。通常它会遍历一个相当广泛和深入的调用树,但如果它很快完成,它就会返回等待。
看起来表现良好的应用在等待下一个外部事件时花费了大部分时间。
表现不佳的应用程序大部分时间都在遍历调用树以响应事件。
提高其性能的方法是找到瓶颈并消除它们。瓶颈几乎总是由调用树中的函数调用组成,在你的代码中,你不知道这些调用很昂贵。不在代码中的调用树部分是您无能为力的,但如果您可以避免调用它们,您就有机会获得加速。
就像您是一名经理一样,试图查看您的员工是否在浪费时间,您也可以不经通知就进来看看他们在做什么。 在软件中,this is how you can do that。
小心那些让你感到困惑的分析器,比如 1) 告诉你例程的“自我时间”,2) 告诉你一个函数被调用了多少次,3) 给你一个庞大但几乎不相关的图表或表格,或者4) 很多有趣但通常不相关的线索,例如缓存未命中和线程切换。
找到瓶颈很容易,因为如果它们很小,它们并不是真正的瓶颈,如果它们很大,在它们浪费的时间里,它们就在堆栈上,等待你注意。 Here's more on that subject.
【讨论】:
DispatchMessage 进行内部调用,而这并不是询问者明确编写的代码的错。它是内部实现的一部分,而不是容易重写或优化的东西。显然我同意他应该检查调用堆栈,看看是什么导致框架在内部调用该函数,但这很可能是一个死胡同。 (另外,我同意你的 cmets;分析软件还有很多不足之处。)