我分析了我的应用程序,发现不是我的函数导致了我看到的延迟,而是 winform 函数。我该如何纠正?有关说明,请参见:
这是分析的结果:
你无法解决这个问题。
该框架正在调用由 Windows API 公开的DispatchMessage
函数GetMessage
,该函数用于将通过对该函数的调用检索到的消息发送到特定窗口的窗口过程。
这里的“慢”部分是 Windows 本身。当这成为您的瓶颈时,您的应用程序已充分优化,您无能为力。
此外,这些配置文件结果不一定告诉您此功能很慢。相反,他们告诉你它被调用了很多(“命中计数”)。这个想法是,经常被调用的函数是代码中的“热点”,值得花一些额外的时间来优化它们的实现(更划算)。但是,在这种情况下,该函数会被大量调用,因为它是 Windows 为您的应用程序处理消息的方式。在非托管代码和本机 Windows API 的世界中,消息有点像您在 .NET 代码中使用的事件。由于任何有趣的事情都必须引发事件,因此负责调用或分派这些事件(消息)的函数必然会被调用很多次。
Windows 应用程序通常包含一个顶级循环,它们在其中等待外部事件,例如鼠标移动/点击和键盘敲击,或内部生成的事件。当一个事件发生时,它会调用适当的处理程序,这可能会做一些事情,也可能做很多事情。通常它会遍历一个相当广泛和深入的调用树,但如果它很快完成,它就会返回等待。
看起来表现良好的应用程序花费了大部分挂钟时间来等待下一个外部事件。
一个看起来表现不佳的应用程序花费大部分时间来遍历调用树以响应事件。
提高其性能的方法是找到瓶颈并消除它们。瓶颈几乎总是由调用树中的函数调用组成,在你的代码中,你不知道这些调用很昂贵。不在您的代码中的调用树部分是您无能为力的,但如果您可以避免调用它们,您就有机会获得加速。
就像您是一名经理一样,试图查看您的员工是否在浪费时间,您可以不经通知就进来看看他们在做什么。在软件中,您可以这样做。
小心那些让你混淆的分析器,比如 1) 告诉你例程的“自我时间”,2) 告诉你一个函数被调用了多少次,3) 给你一个巨大但几乎不相关的图表或表格,或者 4) 很多有趣但通常不相关的线索,如缓存未命中和线程切换。
找到瓶颈很容易,因为如果它们很小,它们并不是真正的瓶颈,如果它们很大,在它们浪费的时间里,它们就在堆栈上,等着你注意。 这里有更多关于这个主题的内容。