我使用 GlowCode(商业产品,类似于 Sleepy)来分析本机 C++ 代码。您运行检测过程,然后执行您的程序,然后查看该工具生成的数据。检测步骤在每个方法的入口点和出口点注入一点跟踪函数,并简单地测量每个函数运行到完成所需的时间。
使用调用图分析工具,我列出了从“最常用”到“最少使用时间”排序的方法,该工具还显示调用计数。只需深入研究百分比最高的例程,就可以向我展示哪些方法使用时间最长。我可以看到有些方法非常慢,但深入研究它们后我发现它们正在等待用户输入或服务响应。有些需要很长时间,因为他们每次调用都会调用一些内部例程数千次。我们发现有人犯了一个编码错误,并且正在为列表中的每个项目重复遍历一个大型链表,而他们实际上只需要遍历一次。
If you sort by "most frequently called" to "least called", you can see some of the tiny functions that get called from everywhere (iterator methods like next()
, etc.) Something to check for is to make sure the functions that are called the most often are really clean. Saving a millisecond in a routine called 500 times to paint a screen will speed that screen up by half a second. This helps you decide which are the most important places to spend your efforts.
我已经看到了两种使用分析的常用方法。一种是做一些“一般”的分析,运行一套“正常”的操作,并发现哪些方法最能减慢应用程序的速度。另一种是做具体的分析,关注具体的用户对性能的抱怨,并通过这些功能来揭示他们的问题。
我要提醒您的一件事是将您的更改限制在那些会显着影响用户体验或系统吞吐量的更改。将鼠标点击缩短一毫秒对普通用户来说并没有什么不同,因为人类的反应时间并没有那么快。赛车手的反应时间在 8 毫秒范围内,一些精英 twitch 游戏玩家甚至更快,但银行柜员等普通用户的反应时间在 20-30 毫秒范围内。好处将是微不足道的。
进行 20 个 1 毫秒的改进或 2 个 20 毫秒的更改将使系统响应更快。如果你能在许多小改进上做一个大改进,那就更便宜更好了。
同样,将每秒处理 100 个用户的服务缩短 1 毫秒将带来 10% 的改进,这意味着您可以改进服务以每秒处理 110 个用户。
令人担忧的原因是,为了提高性能而进行的严格编码更改通常会通过增加复杂性而对代码的结构产生负面影响。假设您决定通过缓存结果来改进对数据库的调用。你怎么知道缓存什么时候失效?是否添加缓存清理机制?考虑一个金融交易,其中循环遍历所有行项目以产生运行总计很慢,因此您决定保留 runningTotal 累加器以更快地回答。您现在必须针对各种情况修改 runningTotal,例如行空、反转、删除、修改、数量变化等。它使代码更复杂,更容易出错。