巴黎的灯光下 发表于 2017-6-22 10:52:09

iOS 性能专项初探

前言
iOS性能测试是什么?
iOS性能测试是指基于iOS平台从:
资源消耗
内存泄露
流量消耗
耗电功率
渲染效果
加载时间
等等.....
这些方面配合一些对应场景去收集数据然后根据数据去分析和定位可能存在的问题!
为什么做这个性能测试?
其实在现在很多企业的功能测试和后台API的测试已经相对较为成熟尤其是功能测试。
但是即使是这样,尽管你的应用有多牛B,你的后台架构有多好,你别忘了你最终还是基于平台来跑,
所以你的应用在平台里面的运行效果不好(Crach率高达百分之几十,内存泄露遍布整个流程)的话,其他的也都是多余的........
做完有什么用?
这个问题我只能说,只要自己用心去一项项去做!研究透!你会发现很多的问题!
比如你设计几个场景然后把这几个场景一个个单独跑一遍,把数据拿出来分析一下,你会发现资源占用较高或者内存泄露严重的步骤一步一步去检查代码会发现确实有问题存在,有可能是垃圾对象冗余,也可能是接口数据太大,json解析消耗较高或者其他等等.....
怎么去做?
Instruments 里面集成的很不错了!所以这里用Instruments 里面的工具来做的!
一项一项来:
1,资源消耗(Cpu、内存):
可以直接用Xcode真机Debug

https://testerhome.com/photo/2015/591e566fa9bc1361cf9b6bc01e85072c.jpg


上图大家都知道怎么看吧,比较简单。也可以用(Activity Monitor)不过没有上面这个方法简单粗暴
2,内存泄露Leaks:

https://testerhome.com/photo/2015/7911c956c385bd76509b62e826a875f2.jpg


选中内存泄露红色区域后下面的列表会把泄露的所以相关内容在下面列表展示,你可以直接找到比例最高的方法直接定位到代码里面!
实例:

https://testerhome.com/photo/2015/5896badb9617811d570867752d8b257b.png


关于:tableView:didSelectRowAtIndexPath ,分析下它的内存过程:
sushiString变量通过autorelease创建,它的引用计数是1.

这行代码使得引用计数增加到2, _lastSushiSelected = ;
这个方法结束时,sushiString的autorelease生效了,这个变量的引用计数减少为1
当再次执行tableView:didSelectRowAtIndexPath这个方法时,_lastSushiSelected被赋值了新指针,老的_lastSushiSelected的引用计数还是1,没有被释放,所以产生了内存泄露。
3,启动耗时
两种方法:一种使用NSLog,另外一种使用Time Profiler。
使用NSLog
CFAbsoluteTime StartTime;
    int main(int argc, char **argv) {
   StartTime = CFAbsoluteTimeGetCurrent();
   // ...
       }
- (void)applicationDidFinishLaunching:(UIApplication *)app {
   dispatch_async(dispatch_get_main_queue(), ^{
      NSLog(@"Launched in %f sec", CFAbsoluteTimeGetCurrent() - StartTime);
   });
   // ...
}使用Time Profiler
Instruments->Time Profiler
Profile你的app
切换到CPU strategy view,找到你的app启动的第一帧
搜索-
找到包含-的最后一帧,即可计算出启动时间

https://testerhome.com/photo/2015/08881d7cdf950fcf380fefa4c30dbbe3.jpg


你也可以粗略看下把有波动的部分选上会有一个时间出来!
3,流量(Network):

https://testerhome.com/photo/2015/42f1f87e33e82d779e1cd1068672ff61.jpg


4,加载时间(Time Profiler):
当我们发现App有点卡的时候,可以通过Time Profiler来看耗时在哪里。

https://testerhome.com/photo/2015/1f96a49f1934cf4cb7c3b453f3d68486.jpg


右边的 call Tree一定要记得选上!下面是这些选项代表的意义!
Separate By Thread:线程分离,只有这样才能在调用路径中能够清晰看到占用CPU最大的线程.
Invert Call Tree:从上到下跟踪堆栈信息.这个选项可以快捷的看到方法调用路径最深方法占用CPU耗时,比如FuncA{FunB{FunC}},勾选后堆栈以C->B->A把调用层级最深的C显示最外面.
Hide Missing Symbols:如果dSYM无法找到你的APP或者调用系统框架的话,那么表中将看到调用方法名只能看到16进制的数值,勾选这个选项则可以隐藏这些符号,便于简化分析数据.
Hide System Libraries:这个就更有用了,勾选后耗时调用路径只会显示app耗时的代码,性能分析普遍我们都比较关系自己代码的耗时而不是系统的.基本是必选项.注意有些代码耗时也会纳入系统层级,可以进行勾选前后前后对执行路径进行比对会非常有用.
5,电量消耗(EnergyDiagnostics)
这个主要是看那个Cpu Activity吧,我也在待研究状态,我怀疑这个工具并不是很准!

https://testerhome.com/photo/2015/cb91bf53465779d4ff259d3795c88773.jpg


上面这些都是浅浅的跟大家说了一下怎么拿到一些数据!
拿到数据之后把他们收集起来分析一下,你会发现有一些场景或操作的系统资源异常,这个时候你可以抱着怀疑的态度去看看代码,也可以跟开发一起去过一下这场景相关的代码,看看是哪里导致这个消耗较大!数据接口量太大?json解析导致?对象没有释放?....

乐哈哈yoyo 发表于 2017-6-22 11:10:53

我问个问题。Network这个只有total的,你怎么过滤应用,或者针对应用场景怎么办

巴黎的灯光下 发表于 2017-6-22 11:19:30

乐哈哈yoyo 发表于 2017-6-22 11:10
我问个问题。Network这个只有total的,你怎么过滤应用,或者针对应用场景怎么办

NetReport 的total针对场景的话可以用步骤结束发送和接收的total减掉步骤前的total 就是步骤所消耗的total?
页: [1]
查看完整版本: iOS 性能专项初探