iOS performance analysis and optimization

Foreword: With the expansion of the project and the increase of functions, the code has not been strictly debugged and optimized, and it will either run in a willful manner or crash in a low-key manner. In the end, users are not happy, and developers are more troubled.

In order to break through this level, it is actually not difficult. First of all, developers can make the code run smoothly as long as they spend a little effort on Instruments, the monitoring and debugging tool that comes with Xcode. If a worker wants to do a good job, he must first sharpen his tools. Instrument is a tool for finding and solving problems for iOS development. Instruments provides a lot of detection functions, focusing on the main categories I use:

  • Analyze—static analysis

  • Leaks - memory leaks (dynamic memory leak detection)

  • Time Profiler: Detects the execution time of profiled code

The principle of interface display

iOS devices are usually 60fps (60 frames per second), which means that the time between two frames is 1/60 of a second, or about 16.7ms. In this 16.7ms, in order to display one frame, the following work is required

The CPU calculates the position and size of each view, decodes the picture, etc., draws it into a texture and hands it to the GPU

The GPU blends the received texture, transforms the vertex, and renders to the framebuffer

Every 16.7ms, a clock signal arrives, and a frame is taken out of the frame buffer and displayed on the screen.

That is to say, when the CPU or GPU is heavily occupied, it is possible that the drawing of one frame cannot be completed within 16.7ms. When the clock signal arrives, the content of the previous frame is obtained, which may cause the interface Caton

offscreen rendering

In iOS, rendering is usually divided into two types: CPU and GPU rendering, and GPU rendering is divided into two types: GPU buffer and non-GPU buffer.

CPU rendering (software rendering), the CPU draws into a bitmap and hands it to the GPU

GPU rendering (hardware rendering)

GPU buffer rendering

Non-GPU buffer rendering (additional buffer opening)

Usually, CPU rendering, and GPU non-frame buffer rendering are collectively referred to as off-screen rendering. Because the CPU and frame buffer are highly optimized for graphic image display, the speed is faster.

When will off-screen rendering be triggered?

Drawn with CoreGraphics' CGContext

drawn in drawRect even if drawRect is empty

Layer has Mask (such as rounded corners) or Shadow

Layer's rasterization shouldRasterize is True

文本(UILabel,UITextfield,UITextView,CoreText,UITextLayer等)

一,Analyze—静态分析

顾名思义,静态分析不需要运行程序,就能检查到存在内存泄露的地方。

1. 使用方法:打开Xcode,command + shift + B;或者Xcode - Product - Analyze;

2. 常见的三种泄露情形:

(1)创建了一个对象,但是并没有使用。Xcode提示信息: Value Stored to 'number' is never read 。翻译一下:存储在'number'里的值从未被读取过。

(2)创建了一个(指针可变的)对象,且初始化了,但是初始化的值一直没读取过。Xcode提示信息: Value Stored to 'str' during its initialization is never read

(3)调用了让某个对象引用计数加1的函数,但没有调用相应让其引用计数减1的函数。Xcode提示信息: Potential leak of an object stored into 'subImageRef' 。 翻译一下:subImageRef对象的内存单元有潜在的泄露风险。

iOS性能分析和优化

二,Leaks—内存泄露

Leaks是动态的内存泄露检查工具,需要一边运行程序,一边检测。

1.使用方法: 进入Xcode,command + control + i ;或者Xcode - Xcode - Open Developer Tool - Instruments; 或者Xcode - Product - Profile。选择Leaks。

一般用静态分析检查过的代码,内存泄露都比较少。测试了有3个项目能点的按钮都点了,能进的页面都进的,Leaks也没检测到泄露。

三,Time Profile

1,打开Time Profile,然后运行想要分析的App

iOS性能分析和优化

2.进入主界面,上下滚动List,让Time Profile采集数据,勾选右侧的Separate by Thread,按线程区分Invert Call Tree,逆向Call Tree,方便我们查看方法调用顺序Hide System Libraries,隐藏系统的库,因为通常系统的代码并不会影响性能

iOS性能分析和优化

3.可以选择一段时间,来分析这段时间CPU的使用情况

iOS性能分析和优化

4.找到占用时间最多的代码

iOS性能分析和优化

然后,双击占用最多的这一行,进入实际的代码,看看到底哪里占用比较多

iOS性能分析和优化

这里,我们看到是这一行代码cell.testLabel?.attributedText = mutableAttr。

占用最多的CPU时间。

我们先来看下整个方法代码,

TableViewCell其实很简单,就一个ImageView(带圆角,阴影),一个UILabel

cellForRowAtIndexPath里会随机的生成100个字符,然后用AttributeText来让UILabel显示

乍一看,问题应该是这个随机生成100个字符的函数啊

iOS性能分析和优化

因为,每一次CellForRow调用的时候,都会计算100次。然后,我们实际分析的时候,发现其实100次对显示来说,真不算什么,也不是卡顿的原因。

那么,为什么设置attributeText占用时间这么多呢?

其实很简单,attributeText是建立在TextKit上的,由于每一次显示都是随机的attributeText,每一次都要重新计算文本的大小,位置等等。另外,UIKit中,提供的文本渲染都是在CPU中进行的,渲染成Bitmap,然后交给GPU,所以导致设置attributeText的时候,占用很多时间。

这里不得不提到:一定不要过早优化,优化的时候尽量依赖于Instrument的分析结果,而不是自己的主观感受。尤其当你还是个新司机的时候。


Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324669962&siteId=291194637