------------------------------------------------------------------
大家好,我是Mike,微软拼音的开发工程师。对于很多应用程序来说,性能决定了其成败。所以在其开发过程中,软件工程师会花大量时间来提高性能。下面就一个微软拼音实际性能问题做具体分析。
------------------------------------------------------------------
某阶段,我们的测试工程师经常抱怨使用微软新体验输入风格,当候选窗口使用“竖排”设置时,输入明显变慢;但是横排没有问题。
我们知道,性能差可能有好些原因导致,常见的有:CPU占用过大;内存占用过多导致频繁的页面切换;大量的磁盘访问;死循环;等等。好,那我们先大致确定下什么原因导致性能下降。
很简单,打开Windows的任务管理器,切换到“性能”Tab,如下图:
然后打开记事本,使用微软拼音新体验打字;这时候发现CPU使用历史曲线忽然升高,而内存曲线变化不大。很明显,这很可能是使用竖排设置时,程序某部分占用CPU过大。
下一步,静态分析代码?不太可行,代码量巨大,一两周都不一定能理出头绪。所以我们只能借助性能分析工具(profiler),就像Visual Studio里面的“性能向导”,我们一般用微软内部的性能工具。不过都差不多,基本原理都是对程序进行“Instrumentation”,然后运行程序,再退出程序,这时候profiler会统计所有函数的调用次数,调用时间,生成一个report。下面用Visual Studio 2008 演示一个简单程序来示例如何操作:
1) 点击Analyze菜单下的“Launch Performance Wizard…”,弹出以下对话框
2) 选择“Instrumentation”,点“Next”,直到“Finish”
3) 运行这个程序,结束后,可以看到生成的report
点击“Current View”下拉框,可以看各种统计数据。这时候,我们所要做的就是仔细分析这个report。一种方法是,具体分析哪个函数出问题,选择“Call Stack”,找占用百分比大的函数分析;另一种方法是,切换到“functions”view,按“Exclusive time”排序,找占用时间最多的几个函数。
具体到实际应用程序中,程序很大,可能调用stack非常复杂。这就需要我们熟悉所分析的程序,同时重点关注可能出问题的部分。
具体到我们这个问题,前面分析到竖排候选窗口显示候选词时候,占用CPU过多。沿着这条线一路追下去,最终发现GetTextExtentPoint32这个Windows GDI API占用时间居多。这时候需要返回去查看代码,发现,在竖排情况下,为了计算最大的候选词宽度,某函数将所有候选词计算一遍,在输入简拼时,候选可能有几千个,而这个GDI函数特花时间,所以导致了输入时很慢。
问题找到了,简单的解决方案是:只算最长的几个候选词,得出最大宽度。