性能分析 ------ CPU运行卡点
目标
如何让CPU优化从模糊到清晰,从感觉这里有性能问题,然后无脑看代码找问题,到有理有据,有数据可依,精确到某个模块函数的优化。
1、精确有效地统计项目中的函数耗时,导出分析报告。
2、通过分析报告指导定位优化。
3、完成迭代优化后,继续测试,通过报告验收优化结果。
(本文主要阐述方法,怎么埋统计点,需要根据实际情况而定)
简述
性能狗(PrefDog):如图已经能分析平均帧率、帧耗时、顿卡等情况,甚至还有时间轴对应的截图,能够较清晰地判断出当时的操作情况,一定程度也可以作为验收优化结果的报告。
但是:最最重要的每帧在处理哪些函数,每个函数耗时又是什么情况,同一个函数多次调用时,峰值、平均值又是什么情况是无法获知的,而这些往往又可能跟代码设计、结构有关系,所以需要自己去插统计点。
设计
思路
1.开启一个http监听,用于接收采样数据;
2.测试过程中采样数据并通过http上报【PS:可以依靠定时器,每隔固定时间进行一次采样数据上报】;
3.测试结束后关闭http监听,对所有采样数据分析整理,导出xlsx报告,示例如下:
采样代码
export class CUpdateData { // 描述; public info: string; // 耗时(ms); public costTime: number; // 当前帧值; public frame: number; // 距离开始采样已经过的时间(ms); public passTime: number; } public static uploadCpuBegin( info : string ) : void { if(!ClientProfile.IsEnable || info == null || info.length == 0) return; let data = new CUpdateData(); data.passTime = UploadBaseData.getCurTime(); // 当前时间戳; data.frame = UploadBaseData._curFrame; // 当前帧; data.info = info; data.costTime = 0; ClientProfile.statistics_data[ info ] = data; } public static uploadCpuEnd( info : string ) : void { if(!ClientProfile.IsEnable || info == null || info.length == 0) return; let data = ClientProfile.statistics_data[ info ]; if ( data == null ) return; data.costTime = UploadBaseData.getCurTime() - data.passTime; if(data.costTime >= ClientProfile.CostMaxTime) { // 压入数据,定时集中发送,TODO...; } }
(采样数据会转成json字符串上报。)
监听代码【nodeJS】
var http=require("http"); http.createServer(function (req, res) { var data = ""; req.on("data",function(chunk){ data += chunk; }) req.on("end",function(){ if(!data) return; // 采样数据是合并上报的,分隔符为“\n” var strs = data.split( "\n" ); for (let i = 0; i < strs.length; i++) { // JSON.parse(strs[i]) ...; } res.end(); } ).listen(8888); // 终端打印IP信息,手机上报就填这个地址; console.log('Server running at '+ getIPAdress() +"port:"+port); function getIPAdress() { let localIPAddress = ""; let interfaces = os.networkInterfaces(); for (let devName in interfaces) { let iface = interfaces[devName]; for (let i = 0; i < iface.length; i++) { let alias = iface[i]; if (alias.family === 'IPv4' && alias.address !== '127.0.0.1' && !alias.internal) { localIPAddress = alias.address; } } } return localIPAddress; }
分析导出
PS:通过nodeJS的库:fs、node-xlsx生成最后xlsx报告。进行了两个维度的分析,
维度一:耗时平均值排序
维度二:时间戳排序,同帧的放在一起
cocosCreator上报示例代码:https://files.cnblogs.com/files/hewei2012/cocosCreator-profile.rar
nodeJS参考代码:https://files.cnblogs.com/files/hewei2012/profile.rar
接口有出入,用于参考。