今天我把在做的这个模块的性能提升了20%,觉得比较欣慰。本来我做的这个模块是没有对性能有所要求,但计算机工作者对运算速度从来都不可能最满意,只有更满意。上个版本我们扫描1T硬盘大约需要2天时间,最近的一次已经能控制在8小时左右。不过这次提升主要来自算法和流程的修改。昨日在看《重构》一书是,里面讲到重构与性能的关系,还特别提到如何优化以及何时优化性能。比较关键的一点是,性能的优化一定是在软件已经稳定的情况下做,并借助性能分析工具重要处理某一部份的代码。根据2/8原则,20%的代码占用了80%的时间。我觉得这个比例可以提高更多。
说一下我是怎么做的吧。我是在Mac下工作的,正好苹果有官方提供的性能分析工具Shark,通过它可以看到每个函数调用的时间比,这样就可以知道那个地方需要优化了(题外话:XCode质量不能算上成,但Performance tools做得还很贴心)。
经过一轮的测试,发现其中一个解析器发费的时间比别的要多出10倍,这可大大出乎我的预料。经过仔细分析,发现调用toupper很占时间,代码是下面这行
std::transform(buf, buf + HTML_MIN_SIZE, buf, toupper);
虽然代码简短,但实际后面做的工作超出我的想像。把这部分处理后,整体一下子大约提升了3%。
这只是代码优化,所以提升的效果不是特别明显。我继续观察,某个函数调用次数非常多,大概占了总共的30%时间。不过这个函数的确需在很多地方调用,而且函数本身也已经做过优化,继续优化的余地也不是很多。于是我就想,可不可以减少调用的次数?在重新整理流程后,发现有一个地方地上一些条件判断后,可以次少很多次调用。但是这个条件判断也需要很多时间。在这种情况下,只好做对比测试了。测试结果表明,在这里优化得到的结果波动非常大,最多是有30%,但有时仅仅4%,最后取平均值15%。
因为时间关系,今天的优化没有做太多,但我相信后面至少还有10%的提升空间。
总结:代码优化是一种比较直观的优化方式,但单次效果不是很明显,通过积沙成塔也可以收到一定的效果。算法优化常常可以达到1个数量级以上的提升,但如果不是关键位置,效果跟代码优化类似。更多的优化的地方还是在于流程方面,只是优化的工作不能在项目前期做,但后面做流程改进又存在风险。所以,优化最终还是一个如何折衷的问题了。!—.—