本文介绍如何运用性能监控(火焰图等)工具,分析应用程序的性能数据以及实现应用程序的CPU、内存优化。
背景信息


CPU优化
定位问题
A公司将性能数据接入到日志服务的性能监控平台后,发现有一个内部库函数regexp.MatchString消耗了应用程序的大量CPU性能。

分析问题

性能对比
A公司将此优化版本标记为version2,然后通过日志服务性能监控平台的数据对比功能分析此次优化带来的性能差异。下图展示了version1与version2的差别,浅蓝色代表部分优化,深蓝色代表全部优化。通过对比发现,对正则表达式进行优化后,上层函数耗时下降77.29%。

验证优化
再次打开QPS统计日志,发现同等资源条件下,10次的平均QPS提升到1399左右,接口性能得到近40倍的提升。

内存优化
定位问题
- alloc_*指标表示从程序启动到目前为止,分配对象的大小或数量,可以帮助定位频繁分配对象的方法,降低Go程序的GC压力。
- inuse_* 指标表示内存中存在的对象大小或数量,可以帮助定位内存泄漏等问题。
A公司通过日志服务性能监控平台分析上述4类指标,发现应用程序的alloc_space指标存在异常,大量内存分配行为都存在于标准库的strings.split函数中。

分析问题
该应用程序的基本业务逻辑是从本地文件读取文件全量数据,然后按行进行切割,接着与输入的内容进行字符串匹配。按行切割时存在大量小字符串分配,通过slice偏移量截取字符串对比,可以避免大量小字符串的分配与释放,优化如下所示。

性能对比
A公司将此优化版本标记为version3,然后通过日志服务的数据对比功能分析此次改动带来的内存性能差异。下图展示了version3与version2的差别,浅蓝色代表部分优化,深蓝色代表全部优化。通过对比发现,过对本次字符串分配进行优化后,核心函数空间分配下降59.46%。

A公司推测内存分配空间的减少也意味着对象分配时间与GC时间的减少,因此推测本次优化可能还会带来CPU性能的提升,因此继续使用CPU性能对比查看CPU性能的变化,发现CPU性能确实提示了19.71%。

验证优化
再次打开QPS统计日志,发现同等资源条件下,10次的平均QPS提升到1840左右,性能再次获得了30%的提升。

总结
本实践中的两次优化,都是对标准库的使用优化。这些问题可能潜藏在每一位开发者的程序中。通过日志服务性能监控平台的查询、聚合、对比能力,您可以快速地定位应用程序潜藏的问题。