iOS性能优化过程浅析
2014-12-02 11:14
190 查看
这一系列文章是我的读书笔记,整理一下,也算是温故而知新。
性能问题的处理流程发现/重现问题
利用工具剖析
形成假设
改进代码和设计在以上的四个步骤中循环反复,直到问题解决。Profile!不要猜!性能优化的主要策略:不要做无用功:不要在启动时花几百ms来做logging,不要为同样的数据做多次查询
试图重用:对于创建过程昂贵的对象,要重用而不是重新创建Table View的cell
Date/Number的formatter
正则表达式
SQLite语句使用更快的方式设计、编程:选择正确的集合对象和算法来进行编程、选择适合的数据存储格式(plist、SQLite)、优化SQLite查询语句
事先做优化对于昂贵的计算,要进行事先计算。iCal中的重复事件,是预先计算出来的,并保存到数据库中。
事先计算并缓存一些对象,可能会占用大量的内存。注意不要将这些对象声明为static并常驻内存。事后做优化:异步加载、懒加载
为伸缩性而做优化:当数据有10条、100条、1000条甚至更多的时候,应用程序的性能不应该对应的呈数量级式的增长,否则无法使用。说起来惭愧,我真的很少遇到性能问题。以前假设中的性能问题,很多是根本不存在的。事前计划也杜绝了不了性能问题的产生,所以不如暂时忘记它吧。当然对于一些常识性的提高性能的设计,仍然是必须的。
很多app的开发者都不重视app的启动速度,这对于碎片化使用情景的用户来说,简直是灾难。iOS应用的启动速度应用启动时,会播放一个放大的动画。iPhone上是400ms,iPad上是500ms。最理想的启动速度是,在播放完动画后,用户就可以使用。如果应用启动过慢,用户就会放弃使用,甚至永远都不再回来。抛开代码不谈,如果抱着PC端游和单机游戏的思维,在游戏启动时强加公司Logo,启动动画,并且用户不可跳过,也会使用户的成功使用率大大降低。iOS系统的“看门狗”为了防止一个应用占用过多的系统资源,开发iOS的苹果工程师门设计了一个“看门狗”的机制。在不同的场景下,“看门狗”会监测应用的性能。如果超出了该场景所规定的运行时间,“看门狗”就会强制终结这个应用的进程。开发者们在crashlog里面,会看到诸如
值得注意的是,Xcode在Debug的时候,会禁止“看门狗”。如何测试启动时间两种方法:一种使用NSLog,另外一种使用Time Profiler。使用NSLog
Profile你的app
切换到CPU strategy view,找到你的app启动的第一帧
搜索
找到包含
UIKit初始化
应用程序callback
第一个Core Animation transaction链接并加载Framework及static lib时需要注意:每个Framework都会增加启动时间和占用的内存
不必要的Framework,不要链接
必要的Framework,不要票房为Optional
只在使用在Deployment Target之后发布的Framework时,才使用Optional(比如你的Deployment Target是iOS 3.0,需要链接StoreKit的时候)
避免创建全局的C++对象初始化UIKit时需要注意:字体、状态栏、user defaults、main nib会被初始化
保持main nib尽可能的小
User defaults本质上是一个plist文件,保存的数据是同时被反序列化的,不要在user defaults里面保存图片等大数据应用程序的回调:
恢复应用程序的状态
用户经常评论app的一个用词是“卡顿”,很大的因素是因为主线程被占用了。用户的事件是在主线程被处理的,包括点击、滚动、加速计、Proximity Sensor。为了保证事件的平滑处理,需要进行如下优化:最小化主线程的CPU占用
将工作“搬离”主线程
不要阻塞主线程最小化主线程的CPU占用前面两篇文章,我们接触到了Time Profiler。使用它可以剖析不同线程的CPU使用情况,并给出调用堆栈的CPU时间占用百分比。如果app“卡顿”,并且在Time Profiler的结果可以找到明确的高占用堆栈,你需要把它优化掉。
为了得到更流畅的交互体验,iOS已经帮我们做了很多事情,Android就没有这么好运了。iOS将以下这些事情搬离了主线程:View和layer的动画(动画绘制前的计算,而不是drawing过程)
Layer的组合计算(drawing后的叠加)
PNG的解码(是的,你没看错;而且利用了CPU的多核心)注意滚动(Scrolling)不是一个动画,而是在Main Run Loop中不断接收事件并且处理。
这里是需要开发者们搞定的部分。磁盘、网络等I/O会阻塞线程,不要把它们放到主线程里。常用的技术有:Grand Central Dispatch(GCD)
NSOperationQueue
NSThreadiOS 4.0后,易用的GCD技术被广泛使用。例如:
使用Dispatch sources
使用带有限制的NSOperationQueue
使用Cocoa Touch提供的异步方法另外一个陷阱是线程安全:UIKit必须要在主线程使用,除了UIGraphics,UIBezierPath,UIImage
大多数CG、CA、Foundation的类,不是线程安全的
如果你使用了ojbc runtime来进行introspection,由于它是thread safe的,可能会导致竞争此外,iOS 4.3添加了
性能问题的处理流程发现/重现问题
利用工具剖析
形成假设
改进代码和设计在以上的四个步骤中循环反复,直到问题解决。Profile!不要猜!性能优化的主要策略:不要做无用功:不要在启动时花几百ms来做logging,不要为同样的数据做多次查询
试图重用:对于创建过程昂贵的对象,要重用而不是重新创建Table View的cell
Date/Number的formatter
正则表达式
SQLite语句使用更快的方式设计、编程:选择正确的集合对象和算法来进行编程、选择适合的数据存储格式(plist、SQLite)、优化SQLite查询语句
事先做优化对于昂贵的计算,要进行事先计算。iCal中的重复事件,是预先计算出来的,并保存到数据库中。
事先计算并缓存一些对象,可能会占用大量的内存。注意不要将这些对象声明为static并常驻内存。事后做优化:异步加载、懒加载
为伸缩性而做优化:当数据有10条、100条、1000条甚至更多的时候,应用程序的性能不应该对应的呈数量级式的增长,否则无法使用。说起来惭愧,我真的很少遇到性能问题。以前假设中的性能问题,很多是根本不存在的。事前计划也杜绝了不了性能问题的产生,所以不如暂时忘记它吧。当然对于一些常识性的提高性能的设计,仍然是必须的。
很多app的开发者都不重视app的启动速度,这对于碎片化使用情景的用户来说,简直是灾难。iOS应用的启动速度应用启动时,会播放一个放大的动画。iPhone上是400ms,iPad上是500ms。最理想的启动速度是,在播放完动画后,用户就可以使用。如果应用启动过慢,用户就会放弃使用,甚至永远都不再回来。抛开代码不谈,如果抱着PC端游和单机游戏的思维,在游戏启动时强加公司Logo,启动动画,并且用户不可跳过,也会使用户的成功使用率大大降低。iOS系统的“看门狗”为了防止一个应用占用过多的系统资源,开发iOS的苹果工程师门设计了一个“看门狗”的机制。在不同的场景下,“看门狗”会监测应用的性能。如果超出了该场景所规定的运行时间,“看门狗”就会强制终结这个应用的进程。开发者们在crashlog里面,会看到诸如
值得注意的是,Xcode在Debug的时候,会禁止“看门狗”。如何测试启动时间两种方法:一种使用NSLog,另外一种使用Time Profiler。使用NSLog
Profile你的app
切换到CPU strategy view,找到你的app启动的第一帧
搜索
找到包含
UIKit初始化
应用程序callback
第一个Core Animation transaction链接并加载Framework及static lib时需要注意:每个Framework都会增加启动时间和占用的内存
不必要的Framework,不要链接
必要的Framework,不要票房为Optional
只在使用在Deployment Target之后发布的Framework时,才使用Optional(比如你的Deployment Target是iOS 3.0,需要链接StoreKit的时候)
避免创建全局的C++对象初始化UIKit时需要注意:字体、状态栏、user defaults、main nib会被初始化
保持main nib尽可能的小
User defaults本质上是一个plist文件,保存的数据是同时被反序列化的,不要在user defaults里面保存图片等大数据应用程序的回调:
恢复应用程序的状态
用户经常评论app的一个用词是“卡顿”,很大的因素是因为主线程被占用了。用户的事件是在主线程被处理的,包括点击、滚动、加速计、Proximity Sensor。为了保证事件的平滑处理,需要进行如下优化:最小化主线程的CPU占用
将工作“搬离”主线程
不要阻塞主线程最小化主线程的CPU占用前面两篇文章,我们接触到了Time Profiler。使用它可以剖析不同线程的CPU使用情况,并给出调用堆栈的CPU时间占用百分比。如果app“卡顿”,并且在Time Profiler的结果可以找到明确的高占用堆栈,你需要把它优化掉。
为了得到更流畅的交互体验,iOS已经帮我们做了很多事情,Android就没有这么好运了。iOS将以下这些事情搬离了主线程:View和layer的动画(动画绘制前的计算,而不是drawing过程)
Layer的组合计算(drawing后的叠加)
PNG的解码(是的,你没看错;而且利用了CPU的多核心)注意滚动(Scrolling)不是一个动画,而是在Main Run Loop中不断接收事件并且处理。
这里是需要开发者们搞定的部分。磁盘、网络等I/O会阻塞线程,不要把它们放到主线程里。常用的技术有:Grand Central Dispatch(GCD)
NSOperationQueue
NSThreadiOS 4.0后,易用的GCD技术被广泛使用。例如:
使用Dispatch sources
使用带有限制的NSOperationQueue
使用Cocoa Touch提供的异步方法另外一个陷阱是线程安全:UIKit必须要在主线程使用,除了UIGraphics,UIBezierPath,UIImage
大多数CG、CA、Foundation的类,不是线程安全的
如果你使用了ojbc runtime来进行introspection,由于它是thread safe的,可能会导致竞争此外,iOS 4.3添加了
一:性能优化策略
性能问题的处理流程发现/重现问题利用工具剖析
形成假设
改进代码和设计在以上的四个步骤中循环反复,直到问题解决。Profile!不要猜!性能优化的主要策略:不要做无用功:不要在启动时花几百ms来做logging,不要为同样的数据做多次查询
试图重用:对于创建过程昂贵的对象,要重用而不是重新创建Table View的cell
Date/Number的formatter
正则表达式
SQLite语句使用更快的方式设计、编程:选择正确的集合对象和算法来进行编程、选择适合的数据存储格式(plist、SQLite)、优化SQLite查询语句
事先做优化对于昂贵的计算,要进行事先计算。iCal中的重复事件,是预先计算出来的,并保存到数据库中。
事先计算并缓存一些对象,可能会占用大量的内存。注意不要将这些对象声明为static并常驻内存。事后做优化:异步加载、懒加载
为伸缩性而做优化:当数据有10条、100条、1000条甚至更多的时候,应用程序的性能不应该对应的呈数量级式的增长,否则无法使用。说起来惭愧,我真的很少遇到性能问题。以前假设中的性能问题,很多是根本不存在的。事前计划也杜绝了不了性能问题的产生,所以不如暂时忘记它吧。当然对于一些常识性的提高性能的设计,仍然是必须的。
二:iOS应用启动速度优化
很多app的开发者都不重视app的启动速度,这对于碎片化使用情景的用户来说,简直是灾难。iOS应用的启动速度应用启动时,会播放一个放大的动画。iPhone上是400ms,iPad上是500ms。最理想的启动速度是,在播放完动画后,用户就可以使用。如果应用启动过慢,用户就会放弃使用,甚至永远都不再回来。抛开代码不谈,如果抱着PC端游和单机游戏的思维,在游戏启动时强加公司Logo,启动动画,并且用户不可跳过,也会使用户的成功使用率大大降低。iOS系统的“看门狗”为了防止一个应用占用过多的系统资源,开发iOS的苹果工程师门设计了一个“看门狗”的机制。在不同的场景下,“看门狗”会监测应用的性能。如果超出了该场景所规定的运行时间,“看门狗”就会强制终结这个应用的进程。开发者们在crashlog里面,会看到诸如0x8badf00d这样的错误代码(“看门狗”吃了坏的食物,它很不高兴)。
场景 | “看门狗”超时时间 |
---|---|
启动 | 20秒 |
恢复运行 | 10秒 |
悬挂进程 | 10秒 |
退出应用 | 6秒 |
后台运行 | 10分钟 |
CFAbsoluteTime StartTime; int main(int argc, char **argv) { StartTime = CFAbsoluteTimeGetCurrent(); // ... 5 } 6 - (void)applicationDidFinishLaunching:(UIApplication *)app { dispatch_async(dispatch_get_main_queue(), ^{ NSLog(@"Launched in %f sec", CFAbsoluteTimeGetCurrent() - StartTime); }); // ... }使用Time ProfilerInstruments->Time Profiler
Profile你的app
切换到CPU strategy view,找到你的app启动的第一帧
搜索
-[UIApplication _reportAppLaunchFinished]
找到包含
-[UIApplication _reportAppLaunchFinished]的最后一帧,即可计算出启动时间iOS App启动过程链接并加载Framework和static lib
UIKit初始化
应用程序callback
第一个Core Animation transaction链接并加载Framework及static lib时需要注意:每个Framework都会增加启动时间和占用的内存
不必要的Framework,不要链接
必要的Framework,不要票房为Optional
只在使用在Deployment Target之后发布的Framework时,才使用Optional(比如你的Deployment Target是iOS 3.0,需要链接StoreKit的时候)
避免创建全局的C++对象初始化UIKit时需要注意:字体、状态栏、user defaults、main nib会被初始化
保持main nib尽可能的小
User defaults本质上是一个plist文件,保存的数据是同时被反序列化的,不要在user defaults里面保存图片等大数据应用程序的回调:
application:willFinishLaunchingWithOptions:
恢复应用程序的状态
application:didFinishLaunchingWithOptions:我一直认为设计的本质是折衷。当你为了100ms的启动速度优化欢欣不已,而无视那长达10秒的启动动画时,应该想想究竟什么是应该做的。
做正确的事情比把事情做好更重要。
三:事件处理-拯救主线程
用户经常评论app的一个用词是“卡顿”,很大的因素是因为主线程被占用了。用户的事件是在主线程被处理的,包括点击、滚动、加速计、Proximity Sensor。为了保证事件的平滑处理,需要进行如下优化:最小化主线程的CPU占用将工作“搬离”主线程
不要阻塞主线程最小化主线程的CPU占用前面两篇文章,我们接触到了Time Profiler。使用它可以剖析不同线程的CPU使用情况,并给出调用堆栈的CPU时间占用百分比。如果app“卡顿”,并且在Time Profiler的结果可以找到明确的高占用堆栈,你需要把它优化掉。
将工作“搬离”主线程 – 隐式并发
为了得到更流畅的交互体验,iOS已经帮我们做了很多事情,Android就没有这么好运了。iOS将以下这些事情搬离了主线程:View和layer的动画(动画绘制前的计算,而不是drawing过程)Layer的组合计算(drawing后的叠加)
PNG的解码(是的,你没看错;而且利用了CPU的多核心)注意滚动(Scrolling)不是一个动画,而是在Main Run Loop中不断接收事件并且处理。
将工作“搬离”主线程 – 显式并发
这里是需要开发者们搞定的部分。磁盘、网络等I/O会阻塞线程,不要把它们放到主线程里。常用的技术有:Grand Central Dispatch(GCD)NSOperationQueue
NSThreadiOS 4.0后,易用的GCD技术被广泛使用。例如:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ // do something in background dispatch_async(dispatch_get_main_queue(), ^{ // do something on main thread }); });GCD的陷阱GCD其实就是线程,只不过提供了一个更高层次的抽象。过多的线程一定会带来性能损失,因此GCD设计了一个最高允许的线程值(对开发者透明,不用管到底有多少)。那么如何解决这个问题呢?将队列串行化
使用Dispatch sources
使用带有限制的NSOperationQueue
使用Cocoa Touch提供的异步方法另外一个陷阱是线程安全:UIKit必须要在主线程使用,除了UIGraphics,UIBezierPath,UIImage
大多数CG、CA、Foundation的类,不是线程安全的
如果你使用了ojbc runtime来进行introspection,由于它是thread safe的,可能会导致竞争此外,iOS 4.3添加了
DISPATCH_QUEUE_PRIORITY_BACKGROUND,它拥有非常低的优先级。这个优先级只用于不太关心完成时间的真正的后台任务,如果要表示较低的优先级,你通常需要的是
DISPATCH_QUEUE_PRIORITY_LOW。不要阻塞主线程即使占用了很少的CPU时间(如果你在Time Profiler中看到这些的数据),也可能会阻塞主线程。磁盘、网络、Lock、dispatch_sync以及向其它进程/线程发送消息都会阻塞主线 程。Time Profiler只能检测出占用CPU过多的堆栈,但检测不了这些IO的问题。大多数的阻塞事件,都会伴随着一个系统调用,如:
read/write- 读写文件
send/recv- 收发网络数据
psynch_mutex_wait- 获得锁
mach_msg- IPC
System Trace这个Instrumentor,记录了所有的系统调用,以及每次调用的等待时间。如果你在System Trace里面发现了CPU Time很低,但Wait Time很高的调用,说明在主线程处理I/O已经严重损害了app的性能。保证主线程的低CPU占用,将I/O移至其它线程,可以大大地提高主线程对交互事件的处理能力。我建议开发者朋友们写代码的时候,除非是以前遇到过的问题,都没有必要假设问题存在。
80%的优化都是不必要的。原文:这一系列文章是我的读书笔记,整理一下,也算是温故而知新。
一:性能优化策略
性能问题的处理流程发现/重现问题利用工具剖析
形成假设
改进代码和设计在以上的四个步骤中循环反复,直到问题解决。Profile!不要猜!性能优化的主要策略:不要做无用功:不要在启动时花几百ms来做logging,不要为同样的数据做多次查询
试图重用:对于创建过程昂贵的对象,要重用而不是重新创建Table View的cell
Date/Number的formatter
正则表达式
SQLite语句使用更快的方式设计、编程:选择正确的集合对象和算法来进行编程、选择适合的数据存储格式(plist、SQLite)、优化SQLite查询语句
事先做优化对于昂贵的计算,要进行事先计算。iCal中的重复事件,是预先计算出来的,并保存到数据库中。
事先计算并缓存一些对象,可能会占用大量的内存。注意不要将这些对象声明为static并常驻内存。事后做优化:异步加载、懒加载
为伸缩性而做优化:当数据有10条、100条、1000条甚至更多的时候,应用程序的性能不应该对应的呈数量级式的增长,否则无法使用。说起来惭愧,我真的很少遇到性能问题。以前假设中的性能问题,很多是根本不存在的。事前计划也杜绝了不了性能问题的产生,所以不如暂时忘记它吧。当然对于一些常识性的提高性能的设计,仍然是必须的。
二:iOS应用启动速度优化
很多app的开发者都不重视app的启动速度,这对于碎片化使用情景的用户来说,简直是灾难。iOS应用的启动速度应用启动时,会播放一个放大的动画。iPhone上是400ms,iPad上是500ms。最理想的启动速度是,在播放完动画后,用户就可以使用。如果应用启动过慢,用户就会放弃使用,甚至永远都不再回来。抛开代码不谈,如果抱着PC端游和单机游戏的思维,在游戏启动时强加公司Logo,启动动画,并且用户不可跳过,也会使用户的成功使用率大大降低。iOS系统的“看门狗”为了防止一个应用占用过多的系统资源,开发iOS的苹果工程师门设计了一个“看门狗”的机制。在不同的场景下,“看门狗”会监测应用的性能。如果超出了该场景所规定的运行时间,“看门狗”就会强制终结这个应用的进程。开发者们在crashlog里面,会看到诸如0x8badf00d这样的错误代码(“看门狗”吃了坏的食物,它很不高兴)。
场景 | “看门狗”超时时间 |
---|---|
启动 | 20秒 |
恢复运行 | 10秒 |
悬挂进程 | 10秒 |
退出应用 | 6秒 |
后台运行 | 10分钟 |
CFAbsoluteTime StartTime; int main(int argc, char **argv) { StartTime = CFAbsoluteTimeGetCurrent(); // ... 5 } 6 - (void)applicationDidFinishLaunching:(UIApplication *)app { dispatch_async(dispatch_get_main_queue(), ^{ NSLog(@"Launched in %f sec", CFAbsoluteTimeGetCurrent() - StartTime); }); // ... }使用Time ProfilerInstruments->Time Profiler
Profile你的app
切换到CPU strategy view,找到你的app启动的第一帧
搜索
-[UIApplication _reportAppLaunchFinished]
找到包含
-[UIApplication _reportAppLaunchFinished]的最后一帧,即可计算出启动时间iOS App启动过程链接并加载Framework和static lib
UIKit初始化
应用程序callback
第一个Core Animation transaction链接并加载Framework及static lib时需要注意:每个Framework都会增加启动时间和占用的内存
不必要的Framework,不要链接
必要的Framework,不要票房为Optional
只在使用在Deployment Target之后发布的Framework时,才使用Optional(比如你的Deployment Target是iOS 3.0,需要链接StoreKit的时候)
避免创建全局的C++对象初始化UIKit时需要注意:字体、状态栏、user defaults、main nib会被初始化
保持main nib尽可能的小
User defaults本质上是一个plist文件,保存的数据是同时被反序列化的,不要在user defaults里面保存图片等大数据应用程序的回调:
application:willFinishLaunchingWithOptions:
恢复应用程序的状态
application:didFinishLaunchingWithOptions:我一直认为设计的本质是折衷。当你为了100ms的启动速度优化欢欣不已,而无视那长达10秒的启动动画时,应该想想究竟什么是应该做的。
做正确的事情比把事情做好更重要。
三:事件处理-拯救主线程
用户经常评论app的一个用词是“卡顿”,很大的因素是因为主线程被占用了。用户的事件是在主线程被处理的,包括点击、滚动、加速计、Proximity Sensor。为了保证事件的平滑处理,需要进行如下优化:最小化主线程的CPU占用将工作“搬离”主线程
不要阻塞主线程最小化主线程的CPU占用前面两篇文章,我们接触到了Time Profiler。使用它可以剖析不同线程的CPU使用情况,并给出调用堆栈的CPU时间占用百分比。如果app“卡顿”,并且在Time Profiler的结果可以找到明确的高占用堆栈,你需要把它优化掉。
将工作“搬离”主线程 – 隐式并发
为了得到更流畅的交互体验,iOS已经帮我们做了很多事情,Android就没有这么好运了。iOS将以下这些事情搬离了主线程:View和layer的动画(动画绘制前的计算,而不是drawing过程)Layer的组合计算(drawing后的叠加)
PNG的解码(是的,你没看错;而且利用了CPU的多核心)注意滚动(Scrolling)不是一个动画,而是在Main Run Loop中不断接收事件并且处理。
将工作“搬离”主线程 – 显式并发
这里是需要开发者们搞定的部分。磁盘、网络等I/O会阻塞线程,不要把它们放到主线程里。常用的技术有:Grand Central Dispatch(GCD)NSOperationQueue
NSThreadiOS 4.0后,易用的GCD技术被广泛使用。例如:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ // do something in background dispatch_async(dispatch_get_main_queue(), ^{ // do something on main thread }); });GCD的陷阱GCD其实就是线程,只不过提供了一个更高层次的抽象。过多的线程一定会带来性能损失,因此GCD设计了一个最高允许的线程值(对开发者透明,不用管到底有多少)。那么如何解决这个问题呢?将队列串行化
使用Dispatch sources
使用带有限制的NSOperationQueue
使用Cocoa Touch提供的异步方法另外一个陷阱是线程安全:UIKit必须要在主线程使用,除了UIGraphics,UIBezierPath,UIImage
大多数CG、CA、Foundation的类,不是线程安全的
如果你使用了ojbc runtime来进行introspection,由于它是thread safe的,可能会导致竞争此外,iOS 4.3添加了
DISPATCH_QUEUE_PRIORITY_BACKGROUND,它拥有非常低的优先级。这个优先级只用于不太关心完成时间的真正的后台任务,如果要表示较低的优先级,你通常需要的是
DISPATCH_QUEUE_PRIORITY_LOW。不要阻塞主线程即使占用了很少的CPU时间(如果你在Time Profiler中看到这些的数据),也可能会阻塞主线程。磁盘、网络、Lock、dispatch_sync以及向其它进程/线程发送消息都会阻塞主线 程。Time Profiler只能检测出占用CPU过多的堆栈,但检测不了这些IO的问题。大多数的阻塞事件,都会伴随着一个系统调用,如:
read/write- 读写文件
send/recv- 收发网络数据
psynch_mutex_wait- 获得锁
mach_msg- IPC
System Trace这个Instrumentor,记录了所有的系统调用,以及每次调用的等待时间。如果你在System Trace里面发现了CPU Time很低,但Wait Time很高的调用,说明在主线程处理I/O已经严重损害了app的性能。保证主线程的低CPU占用,将I/O移至其它线程,可以大大地提高主线程对交互事件的处理能力。我建议开发者朋友们写代码的时候,除非是以前遇到过的问题,都没有必要假设问题存在。
80%的优化都是不必要的。原文:http://www.codeceo.com/article/ios-high-performance.html
相关文章推荐
- iOS性能优化过程浅析
- iOS性能优化过程浅析
- iOS性能优化浅析
- 了解html页面的渲染过程以备学习前端的性能优化(续)
- 2011年2月--2011年7月数据库性能优化过程
- RO 收发数据的过程优化 性能提升可观!!
- sql server 存储过程的优化:简单测试在存储过程中临时表与union all的性能差别
- 应用系统性能优化过程
- 利用预渲染解决优化性能问题IOS
- 网站性能优化之HTTP请求过程
- 网站性能优化之HTTP请求过程简述
- Oracle数据库的系统性能优化策略浅析
- 性能优化 以及 控件和组件概念浅析
- 优化图形性能(iOS)
- iOS性能优化系列
- (转)!!频繁分配释放内存导致的性能问题的分析 --(附)malloc分配原理浅析 mmap关注焦点 如何优化分配内存
- 浅析SQL Server数据库的性能优化
- 浅析 innerHTML 性能优化的原理
- SQL Server性能调优之执行计划深度剖析 第一节 浅析SQL执行的过程
- iphone ios 性能优化