我之前已经在 SO 上提出过这一点,其他人也是如此。
如果您的目标是提高性能(以挂钟时间衡量),那么到目前为止,最好的工具就是调试器本身及其“暂停”按钮。让我告诉你为什么。
首先,让我们看一个好的 Profiler
在分析器中,ANTS 可能和他们来的一样好。当我在应用程序上运行它时,屏幕顶部如下所示:
请注意,您必须选择要查看的时间跨度,并且您必须选择要查看 CPU 时间还是文件 I/O 时间。在该时间范围内,您会看到如下内容:
它试图展示 ANTS 认为的“热路径”,仅考虑 CPU 时间。当然,它强调包容性的“与孩子相处的时间(%)”,这很好。在这样的大型代码库中,请注意自时间“时间 (%)”有多小?这是典型的,你可以明白为什么。
这就是说,您当然应该忽略包含百分比较低的函数,因为即使您可以将它们减少到无操作,您在该间隔内的总时间也不会超过它们的包含百分比。
因此,您查看具有高包容性百分比的函数,并尝试在其中找到一些东西以减少它们花费的时间,通常是通过 a) 让它们对子函数进行更少的调用,或者 b) 让函数本身被调用较少的。
如果您找到并修复它,您将获得一定百分比的加速。然后你可以再试一次。当你找不到任何可以修复的东西时,你就宣布胜利并把你的分析器放在另一天。
请注意,您可能已经修复了其他问题以加快速度,但如果分析器没有帮助您找到它们,您就认为它们不存在。这些可以是真正的大睡眠者。
现在让我们来一些手动样本
在困扰我的阶段,我只是随机暂停了应用程序六次,因为它让我等待。每次我拍摄调用堆栈的快照时,我都会仔细查看程序在做什么以及为什么这样做。其中三个样本如下所示:
外部代码
Core.Types.ResourceString.getStringFromResourceFile 第 506
行 Core.Types.ResourceString.getText 第 423
行 Core.Types.ResourceString.ToString 第 299 行
外部代码
Core.Types.ResourceString.getStringFromResourceFile 第 528
行 Core.Types.ResourceString.getText 第 423 行
核心.Types.ResourceString.ToString Line 299
Core.Types.ResourceString.implicit operator string Line 404
SplashForm.pluginStarting Line 149
Services.Plugins.PluginService.includePlugin Line 737
Services.Plugins.PluginService.loadPluginList Line 1015
Services.Plugins.PluginService.loadPluginManifests Line 1074
Services.Plugins.PluginService.DoStart 第 95 行
Core.Services.ServiceBase.Start 第 36
行 Core.Services.ServiceManager.startService 第 1452
行 Core.Services.ServiceManager.startService 第 1438
行 Core.Services.ServiceManager.loadServices 第 1328
行 Core.Services.ServiceManager.Initialize 第 346 行
Core.Services.ServiceManager .Start Line 298
AppStart.Start Line 95
AppStart.Main Line 42
这就是它正在做的事情。它正在读取资源文件(即 I/O,因此查看 CPU 时间不会看到它)。它读取它的原因是获取插件的名称。插件名称在资源文件中的原因是将来可能需要将该字符串国际化。无论如何,获取它的原因是在加载插件期间名称可以显示在启动屏幕上。大概原因是,如果用户想知道什么花了这么长时间,启动画面会告诉他们正在发生的事情。
这六个样本证明,如果名称不显示,或者显示但以更有效的方式获取,则应用程序的启动速度大约会增加一倍。
我希望你能看到,没有任何一个通过显示测量值来工作的分析器能够如此迅速地产生这种洞察力。
即使分析器通过挂钟时间而不是 CPU 显示包含百分比,它仍然会让用户试图弄清楚发生了什么,因为在总结例程的时间时,它几乎失去了所有解释性上下文如果它正在做的事情是必要的。
仅查看汇总统计数据和查看代码时,人类的倾向是说“我可以看到它在做什么,但我看不到任何改进它的方法”。
那么“统计意义”呢?
我一直听到这个,它来自对统计的天真。
如果六分之三的样本显示有问题,这意味着问题使用的最有可能的实际百分比是 3/6=50%。这也意味着如果您多次这样做,平均成本将为 (3+1)/(6+2),这也是 50%。如果您节省 50% 的时间,则可以将速度提高 2 倍。成本有可能低至 20%,在这种情况下,加速只有 1.25 倍。成本可能高达 80% 的可能性相同,在这种情况下,加速将是 5 倍(!)。所以,是的,这是一场赌博。加速可能小于估计值,但不会为零,而且同样可能非常大。
如果需要更高的精度,则可以采集更多的样本,但如果牺牲了通过检查样本获得的洞察力来获得统计精度,那么很可能找不到加速。
PS这个链接显示了找到所有问题的关键重要性——不要遗漏任何问题。