性能分析 ------ 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;
    // 采样数据是合并上报的,分隔符为“
”
    var strs = data.split( "
" );
    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

接口有出入,用于参考。

原文地址:https://www.cnblogs.com/hewei2012/p/13227318.html