耗电量分析是衡量应用性能表现的一个重要指标,要做好一款app,不仅仅是实现功能,我们需要考虑很多性能指标,让用户用的更爽,在开发过程中,要充分考虑到各项性能指标,比如定位精度,更高的精度,往往意味着更高的能耗,因此要平衡好精度和功耗,避免我们的app过多的过多的电量消耗,而界面卡顿可能意味着大量的多余计算,不仅影响流畅度,影响电量消耗,网络的不合理使用,也会增加耗电量,这些都是影响耗电量和用户体验的重要因素,因此必须要重视app耗电量。

1.耗电量概念

 `x 轴`为时间,`y 轴`为电量消耗的坐标图

  • Idle 表示app处于休眠状态,几乎不使用电量。
  • Active状态说明app处于工作状态,用电量比较高,图中的第二个 Active 的耗电远高于第一个,这是因为app所做的工作类型不同而导致的。
  • Overhead指的是调起硬件来支持app功能所消耗的电量,这部分是支持硬件工作必要的电量消耗。
  • 图中横线以下所包区域是固定开销(Fixed Cost),横线以上区域是动态开销(Dynamic cost)。

2.节省电量的四个基本原则:

  • 识别:想清楚你需要app在特定时刻需要完成哪些工作,如果是不必要的工作,考虑延后执行或者省去。

  • 优化:优化app的功能实现,尽可能以更有效率的方式去完成功能。

  • 合并:不需要立刻获取,可以延后合并执行,比如合并网络

  • 减少:在满足需求的基础上,尽量减少做重复工作的频率。

一、耗电大户

 1.CPU

app做的每件事几乎都需要用CPU,所以CPU是电能消耗大户,高CPU使用时会迅速消耗掉用户的电池电量,所以我们要更合理的使用CPU,降低能耗。

 2.网络

app进行网络通信时,蜂窝数据和Wi-Fi等元器件开始工作就会消耗大量电能,应减少数据传输,合并网络请求,适当的网络延时等。

2.定位

app为了记录用户的活动或者提供基于位置的服务会进行定位。定位精度越高,定位时间越长,消耗电量也就越多。

4.GPU

app内容每次更新到屏幕上都需要消耗电能处理像素信息。动画和视频格外耗电。不经意的或者不必要的内容更新同样会消耗电能,所以UI不可见时,应该避免更新其内容。

5.传感器

长时间用不上加速度计、陀螺仪、磁力计等设备的动作数据时,应该停止更新数据,不然也会浪费电能。应按需获取,用完即停。蓝牙活动频度太高会消耗电能,应该尽量分批、减少数据轮询等操作。

6.Multimedia(多媒体)

7.Camera(相机)

二、测试工具

1.Energy Impact

 1.1Average energy Imapct

Average energy Imapct代表的是app的耗电量评级,low(绿色区域)high (黄色区域)very high(红色区域)。通过这张图,我们可以大致了解 app 电量的使用情况。理想的状态是 app 处于 low、high 状态。如果处于very high状态,我们需要分析哪些功能导致耗电量大涨。

1.2Average Componet Utilization

Average Componet Utilization展示的是OverheadCPUNetWorkLocationGPU各部分耗电量的占比,通过这个占比,我们可以分析各部分耗电量是否较高。

1.3Energy Impact

Energy Impact会实时展示电量消耗,每个柱子代表每秒的电量消耗,通过每个柱子由不同的颜色组成,展示各部分电量消耗的比例,依次是Overhead(红色)、CPU(蓝色)、网络(深黄)、定位(淡黄)、GPU(绿色)、后台(深灰)、前台(淡灰)、Suspend(白色)

1.4总结

在使用Energy Impact的过程中,首先可以观察Average energy Imapct。了解app的整体耗电量情况,处在什么位置,对整体有个大概的了解,然后通过Average Componet Utilization来观察app整体耗电量中,具体哪一部分占比较高,最后使用Energy Impact进行实时分析,分析页面各部分消耗是否是必要的,比如某个页面只在进入的时候需要获取经纬度,后面不需要实时获取经纬度,那么在进入页面获取经纬度以后,就要将定位关闭,以减少电量消耗。

优点:
实时性高、数据分析可以通过图形直观展示、可以获取`Overhead(红色)、CPU(蓝色)、网络(深黄)、定位(淡黄)、GPU(绿色)、后台(深灰)、前台(淡灰)、Suspend(白色)等数据和各部分数据占比。

缺点:
颗粒度较大,想做详细的分析,需要借助,其它工具。
针对CPU的消耗情况,可以通过Time Profiler来进行分析,分析具体哪部分代码消耗较多;
使用Network Profiler来分析网络的消耗情况;
 

2.Energy Log

方式一,适用于测试人员,测试时不需要把手机连接到Xcode,测试完成后在连接到Xcode查看数据

  • iPhone->设置->开发者->Loggin->Start Recording
  • 然后打开要测试的App点击一遍要操作的流程,然后Stop Recording
  • Xcode->Open Developer Tool->Instruments->Energy Log
    • 选择要测试的设备和App
    • 左上角File->Import Logged Data From Device

方式二,适用于开发人员,测试时需要把手机连接到Xcode

  • 双击打开EnergyLog, 直接点击红色圆点运行程序
  • App启动后,在里面进行各种操作
  • 点击黑色方块停止检测,这个时候可以看到数据,如果正在检测是看不到数据的

使用说明

  • 可以看到CPU活动比例,网络活动比例,亮度状态,手机睡眠状态,手机连接蓝牙状态,手机连接wifi状态,手机GPS状态这次都是手机耗电的构成部分。
  • Energy Usage Log 代表能耗消耗级别,有 0 到 20 的级别,表示应用在任何给定时间使用了多少电量,值越大表示越耗电。可以用来分析app的总体能耗。
    1/20表示运行该app电池生命会有20个小时;20/20表示运行该app电池电量仅有1小时生命

  • CPU Activity Log 代表cpu能源消耗,包括 :Foreground app ActivityGraphics ActivityMedia ActivityOther Activity

  • Network Activity Log 代表网络能源消耗,包括 :Cellular inCellular outWi-Fi InWi-Fi Out

  • Display Brightness Log 代表屏幕消耗。

  • Sleep/Wake Log 代表仪器捕获有关设备当前状态的信息。

  • Bluetooth On/Off Log 代表蓝牙开关状态。

  • Wi-Fi On/Off Log 代表Wi-Fi开关状态。

  • Gps On/Off Log 代表Gps开关状态。

2.2总结

在使用Energy Log过程中,可以通过横向比较各个维度的数据,来分析各部分的能源消耗,分析能耗的使用情况,更合理的使用手机电量。

还有一种方式是通过Sysdiagnose分析, 可参考iOS性能优化之耗电检测,  这里就不写了, 下面分析实例.

Sysdiagnose是苹果的日志系统,记录电池、第三方APP、各种系统功能和应用的所有运行情况,将Sysdiagnose导出并解压后,我们能在文件夹中找到名为powerlog_xxxxx.PLSQL的文件,用数据库可视化工具(本文使用SQLiteStudio)打开,其中详细记录了我们进行iOS耗电量测试的所需的数据。

三、案例分析

 上面是使用Energy Log来测试页面的电量消耗情况,红色部分是Overhead,表示调起硬件的正常电量消耗,其占据页面57.1%,网络占10.2%,cpu占1.2%,Location占31.1%,但在这个页面中,GPS是一直开启的,也就是图中的黄色部分,实际情况是是不需要一直开启GPS定位,这一部分存在优化空间,按需要开启和关闭GPS开关。

总结

在进行电量消耗测试时,需要对页面需求进行具体分析,用来判别页面中网络、CPU、GPU、GPS各部分的电量消耗是否是合理和必要的,上面例子的情况,GPS没必要一直开启,可以在不需要使用时关闭,存在优化空间。关于更多电量优化建议,可以参考苹果官方Apple Energy Guide或者这篇翻译App功耗优化建议,会从网络、CPU、GPU、GPS等方面,更详细的角度来分析耗电量优化。

四、优化建议

1.网络

只要app执行网络操作,就会产生大量的见解能耗,网络硬件为了响应下一次任务,往往会持续活跃一段时间,下面是多次网络的能耗图。

 1.1 缩减网络请求

  1. 减少、压缩网络数据。可以降低上传或下载的多媒体内容质量和尺寸等。

  2. 使用缓存,不要重复下载相同的数据。

  3. 使用断点续传,否则网络不稳定时可能多次传输相同的内容。

  4. 网络不可用时不要尝试执行网络请求。

  5. 让用户可以取消长时间运行或者速度很慢的网络操作,设置合适的超时时间。

  6. 网络请求失败后用SCNetworkReachability的通知监测网络状态,网络可用后再重试。

1.2 延迟联网

  1. 分批传输。比如,下载视频流时,不要传输很小的数据包,直接下载整个文件或者一大块一大块地下载。如果提供广告,一次性多下载一些,然后再慢慢展示。如果要从服务器下载电子邮件,一次下载多条,不要一条一条地下载。

  2. 网络操作能推迟就推迟。如果通过HTTP上传、下载数据,建议使用NSURLSession中的后台会话,这样系统可以针对整个设备所有的网络操作优化功耗。将可以推迟的操作尽量推迟到设备充电状态并且连接Wi-Fi时进行,比如同步和备份工作。

2.定位

  1. 如果你的app只是需要快速确定一下用户的位置,最好用CLLocationManager的requestLocation (iOS9引入)方法。定位完成之后会自动让硬件断电。

  2. 除非是在导航的时候,app大部分时间不需要实时更新,降低位置的更新频率。

  3. 尽量降低定位精度。iOS设备默认采用最高精度定位,如果你的app不是确实需要米级的位置信息,不要用最高精度(kCLLocationAccuracyBest)或10米左右的精度(kCLLocationAccuracyNearestTenMeters)。一般来说Core Location提供的精度比你设置的要好,比如你设置为3公里左右的精度,可能会收到100米左右的精度信息。

  4. 如果定位精度一直达不到设置的精度时,停止更新位置,稍后再试。

  5. 需要后台更新位置时,尽量把pausesLocationUpdatesAutomatically设为YES,如果用户不太可能移动的时候系统会自动暂停位置更新。

  6. 后台定位时延时更新位置。如果要做一个健身类的软件追踪用户徒步的距离,可以等用户移动一段距离或者过一段时间之后再更新位置,这样可以让系统优化能耗。

3.CPU

3.1尽量减少计时器使用

使用计时器时,设置一个合适的超时时,不再需要时及时关闭重复性定时器。用事件通知代替定时器。有些app用定时器监控文件内容、网络或者其他状态的变化,这会导致CPU无法进入闲置状态而增加功耗。

3.2减少后台工作

实现UIApplicationDelegate中的方法,应用进入后台前做好暂停任务,保存数据等工作。如果确实需要完成用户执行的一些任务,应该调用UIApplicationDelegate中的beginBackgroundTaskWithExpirationHandler: 方法,这样后台任务可以继续执行几分钟。任务执行完毕后一定要调用endBackgroundTask:方法,不要等着系统强行挂起进程。

3.3用QoS分级有序工作

多个app和众多操作需要共享CPU、缓存、网络等资源,为了保持高效,系统需要根据不同任务的优先级智能地管理这些工作。比如更新UI这种重要的事需要多分配资源,而一些后台任务可以延迟一些执行。服务质量(quality of service, 以下简称QoS, iOS8引入)级别可以通过NSOperation, NSOperationQueue, NSThread objects, dispatch queues, 和pthreads (POSIX threads)指定工作的优先级。

3.4优化I/O访问

app每次执行I/O任务,比如写文件,会导致系统退出闲置模式。而且写入缓存格外耗电。通过下列方法可以提高能效、改善app性能。

  1. 减小写入数据。数据有变化再写文件,尽量把多个更改攒到一起一次性写入。如果只有几个字节的数据改变,不要把整个文件重新写入一次。如果你的app经常要修改大文件里很少的内容,可以考虑用数据库存储这些数据。

  2. 避免访问存储频度太高。如果app要存储状态信息,要等到状态信息有变化时再写入。尽量分批修改,不要频繁地写入这些小变动。

  3. 尽量顺序读写数据。在文件中跳转位置会消耗一些时间。

  4. 尽量从文件读写大数据块,一次读取太多数据可能会引发一些问题。比如,读取一个32M文件的全部内容可能会在读取完成前触发内容分页。

  5. 读写大量重要数据时,考虑用dispatch_io,其提供了基于GCD的异步操作文件I/O的API。用dispatch_io系统会优化磁盘访问。

  6. 如果你的数据由随机访问的结构化内容组成,建议将其存储在数据库中,可以使用SQLite或Core Data访问。特别是需要操作的内容可能增长到超过几兆的时候。

  7. 了解系统如何缓存文件、如何优化缓存的使用。如果你不打算多次引用某些数据,不要自己缓存数据。

4.GPU

  1. 减少app使用的视图数量。

  2. 少用运算获得圆角,不论view.maskToBounds还是layer.clipToBounds都会有很大的资源开销.

  3. 尽量少用透明或半透明,会产生额外的运算.

  4. 执行动画时不要修改帧率。比如,你的app帧率是60fps,整个动画就保持这个帧率不要变。

  5. 视频播放时,app尽量不要在全屏视频上添加额外的图层(即使是隐藏的图层)

5.优化通知

  1. 尽量用本地通知(local notification),如果你的app不依赖外部数据,而是需要基于时间的通知,应该用本地通知,可以让设备的网络硬件休息一下。

  2. 远程推送有两个级别,一个是立即推送,另一个是针对功耗优化过的延时推送。如果不是真的需要即时推送,尽量使用延时推送。

五、总结

耗电量分析是应用开发中很难的课题,也是衡量性能的重要指标,做好电量优化,可以大幅度提升用户体验,在实际开发过程中,电量消耗往往是一个综合的结果,小到日常的代码习惯,积少成多,大到网络的乱用、不合理的网络超时、不合理的定位使用、不合理的CPU使用,都会带来能耗的过多消耗,而这些问题仅仅会影响电量,还会影响用户体验,而对于这一个很多因素综合起来的结果,我们需要提高日常开发的代码质量,了解不同实现方式的差异点,优化页面卡顿,优化网络使用,优化GPS使用等等,只有综合这些因素,最终获得较好的用户体验。

在做耗电量分析的时候,首先要清楚耗电量较大的点,比如:网络、定位、CPU、GPU,从这些点来入手分析,再详细分析每个点,细分每个点中的一些细节的影响,比如:网络中可能会存在导致耗电量过高的因素,我们可以使用哪些优化方法,同时根据我们的需求特点,怎么来优化,最终找到可优化点的,找到解决方案,来优化耗电量。

在优化点寻找的过程中,我们首先可以使用Energy Impact来实时分析,各个维度指标是否有问题,占比是否合理,然后在通过Time ProfilerNetwork ProfilerLocation Profiler等工具对各项指标进行详细分析,寻找优化点。
其次我们可以使用Energy Log来横向对比各个维度的数据,来分析各个维度对总功耗的影响,比如:wifi数据传输和4G数据传输时,耗电量的对比,打开蓝牙和未打开蓝牙,能耗数据的对比,查看各个维度对能耗消耗影响的权重。也可以进行各种能耗数据的对比分析,以及优化前后的能耗数据对比,获取最终的优化效果。

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐