关闭

iOS 基础性能优化技巧(二)

标签: ios性能
426人阅读 评论(0) 收藏 举报
分类:

基础性能优化技巧

本文为调试程序提供一些实际的经验,列出一些需要用性能工具来监控的指标并且提供优化性能方面的 tips。

需要监控的区域

程序主路径代码

当你设计程序时,需要考虑用户最可能使用的主路径和工作流。当完成这部分的开发任务后,确保监控这些代码保证它们的性能不会低于预期标准。如果过低,就应该立刻优化它。

不同APP 的主路径代码也不同,例如,文字处理应用可能更需要保证文字输入和显示时流畅,然而文件管理应用可能需要扫描文件和存储到硬盘时更快速。这取决于你来决定你的用户最可能产生哪些操作。

关于如何加快程序响应可以参考Code Speed Performance Guidelines

自定义绘制

大多数程序会执行很多绘制操作。如果你的程序只使用标准化的窗口和控件,你就可能不需要花费很大心思关心绘制性能。然而,如果你做了一些自定义绘制操作,就需要监控这些绘制代码并保证它们的性能表现达标。通常情况,如果支持以下任何一种技术,就应该对绘制代码进行优化:

  • Live resizing
  • 自定义视图绘制,尤其是view可以局部更新时;
  • 纹理图形
  • 整个透明 view
    更多关于优化自定义绘制代码请参考Drawing Performance Guidelines

启动时间

启动时间是你初始化程序数据结构并准备接收用户输入。然而,很多应用在启动阶段做了很多不必要的操作。很多案例中,在启动时间做的一些操作可以延迟到应用展现 UI 界面并开始处理事件之后。这样的延后可以给你的用户带来应用响应很快的感觉,更容易获得一个好的第一印象。

更多关于优化启动时间请参考Launch Time Performance Guidelines

文件读写

文件系统是从内存和 CPU 获取数据的瓶颈。当读取文件时,数以百万计的指令会被运行。因此,因此检查程序使用文件的方式,并保证这些文件实际上确实是必须的,并且可以合理被使用。

最小化使用中的文件是改善文件相关性能表现的方法之一。当读取文件时,请谨记:

  • 理解系统如何缓存文件,并知道如何优化缓存的使用。避免自动缓存数据,除非你计划两次以上使用它。
  • 尽可能连续的读写数据。跳过某个文件会花费额外的时间来寻找新地址。
  • 尽可能从文件读取大块数据,记住一次性读取过大的数据可能导致不同的问题。例如,整个读取一个32MB 的文件可能导致操作完成之前需要对这些内容进行分页。
  • 避免不必要的关闭和重新开启文件。如果缓存可用,这样做可能导致尽管数据没有变化,但缓存仍被更新。

更多关于定义和解决文件相关性能问题请参考File-System Performance Guidelines

应用占用的空间

代码的体积可以对系统性能造成很大的影响。更多的内存被用于你的应用,那么分配给系统和其他应用的资源就会越少。内存压力会导致分页和全局性能降低。

管理应用所占用的空间其实就是梳理代码和数据结构。需要保证合理使用内存并且不会对无关的内存进行读写。导致大量内存占用的问题有如下几种:

  • 包含不会被调用的代码。
  • 静态或常量数据被储存在可读写的页中。在分页过程中,这些数据会被不必要的写入硬盘。
  • 程序导出超过实际使用量的符号文件。
  • 代码没有被编译器和连接器优化。尝试改变编译器设置看一下哪种设置对应用最适合。
  • 应用中包含过多框架。只加载应用中用到的框架。
    更多关于如何找到和修复代码占用的问题请参考Code Size Performance Guidelines

内存分配

应用为持久化和临时的数据结构分配内存。每次内存分配都会消耗资源,包括 CPU 时间和内存消耗。理解何时分配内存和内存如何被使用,可以帮助你减少对这两个方面的资源消耗。

理解程序的内存使用可以帮助决定是否有必要减去该次使用。可以使用性能工具来找到自动释放的OC 对象在导致过多分页前被回收。还可以利用这些工具来查找内存泄露引起的 Bug。查看调用 malloc 的次数可以帮助找到哪些地方可以重新利用内存空间,而不是开辟新的内存。

另一条分配内存的重要原则是懒加载。当真正需要使用内存的时候再开辟空间。另外一些对内存分配进行懒加载可参考Be Lazy

更多关于优化内存分配请参考Memory Usage Performance Guidelines

基本优化 tips

开始开发新应用之前,有一些提升性能的方面需要考虑。尽管并不能在每个案例中都采用,但至少在设计阶段应该考虑它们。

懒加载

一个改善性能的非常简单的方法是,保证你的应用不会进行任何不必要的工作。应用每时每刻都应响应用户当前的请求,不要提前预测后续的请求。如果不是立刻需要使用某个资源,例如不要提前加载包含设置窗口的nib 文件。这种操作占用时间来执行,因为它需要读写文件系统,如果用户一直不打开设置窗口,加载这个 nib 文件就是浪费时间。

基本的原则是等到用户请求从应用中获取什么,再调用必须的资源满足这次请求。只有缓存可以带来可度量的性能优势时,再将数据写入缓存。本以为预加载缓存会让应用运行更快,但实际上导致性能陷入低内存的情景。在这样的场景中,你的缓存数据可能在被使用之前就存储到了硬盘中。因此,通过缓存获取数据就会产生损失,因为数据现在被使用时,必须从硬盘中读2次。如果确实需要缓存数据,就在操作执行过一次之后再缓存。

其他可以懒加载的部分:

  • 在真正需要内存空间时再开辟。
  • 不要零初始化内存块。调用 calloc 方法懒加载。
  • 给予系统懒加载应用的机会。配置和规划你的代码,便于系统仅加载本次操作所需的代码。
  • 在真正需要数据时,再读取文件内容。

体验性能

感觉到的性能和实际的性能在很多案例中同样重要。一些应用任务可以使用 dispatch queue在后台或空闲时运行。这样使应用的主线程一直响应UI,并对用户响应更加迅速。当你设计应用时,考虑一下哪些任务可以被移到后台线程中。例如,如果你的程序需要扫描大量文件或进行长时间的计算,就可以使用一个 dispatch queue。

另一种提高感觉上的性能的方式是确保应用启动迅速。当启动时,延迟所有对于快速展现 UI 作用不大的任务。例如,延迟创建大型数据结构,直到应用完成启动并展示主窗口。如果你使用主窗口展现一些数据,这些数据必须在启动时间内准备就绪,就先展示出窗口,再显示一个进度条或用其他状态提示信息告知用户数据正在被加载。对于使用插件的应用,等实际需要用到插件时再加载。

优化任务并发

在多核电脑上,并发性是改善体验性能和实际性能的另一种方式。可以同时执行多任务的应用可以在多核电脑上并发执行这些任务。尽管是单核电脑,将代码正确分解为多个、异步任务可以带来体验上的速度提升。

特别是,你应该使用子队列来执行自定义任务,空出主线程来执行用户事件和更新 UI。

在开始增加对并发的支持之前,花一些时间考虑你的应用如何更高效的实现响应任务。把代码拆分为不同的任务需要考虑数据结构和代码路径。共享数据结构的任务可能需要使用串行队列来对数据结构进行同步。

更多关于如何实现并发请参考Concurrency Programming Guide

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:27209次
    • 积分:520
    • 等级:
    • 排名:千里之外
    • 原创:22篇
    • 转载:6篇
    • 译文:0篇
    • 评论:3条
    文章分类