iOS耗电量优化
前言-理论篇耗电量分析是衡量应用性能表现的一个重要指标,要做好一款app,不仅仅是实现功能,我们需要考虑很多性能指标,让用户用的更爽,在开发过程中,要充分考虑到各项性能指标,比如定位精度,更高的精度,往往意味着更高的能耗,因此要平衡好精度和功耗,避免我们的app过多的过多的电量消耗,而界面卡顿可能意味着大量的多余计算,不仅影响流畅度,影响电量消耗,网络的不合理使用,也会增加耗电量,这些都是影响耗电
耗电量分析是衡量应用性能表现的一个重要指标,要做好一款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
展示的是Overhead
、CPU
、NetWork
、Location
、GPU
各部分耗电量的占比,通过这个占比,我们可以分析各部分耗电量是否较高。
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 Activity
、Graphics Activity
、Media Activity
、Other Activity
。 -
Network Activity Log
代表网络能源消耗,包括 :Cellular in
、Cellular out
、Wi-Fi In
、Wi-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 缩减网络请求
-
减少、压缩网络数据。可以降低上传或下载的多媒体内容质量和尺寸等。
-
使用缓存,不要重复下载相同的数据。
-
使用断点续传,否则网络不稳定时可能多次传输相同的内容。
-
网络不可用时不要尝试执行网络请求。
-
让用户可以取消长时间运行或者速度很慢的网络操作,设置合适的超时时间。
-
网络请求失败后用SCNetworkReachability的通知监测网络状态,网络可用后再重试。
1.2 延迟联网
-
分批传输。比如,下载视频流时,不要传输很小的数据包,直接下载整个文件或者一大块一大块地下载。如果提供广告,一次性多下载一些,然后再慢慢展示。如果要从服务器下载电子邮件,一次下载多条,不要一条一条地下载。
-
网络操作能推迟就推迟。如果通过HTTP上传、下载数据,建议使用NSURLSession中的后台会话,这样系统可以针对整个设备所有的网络操作优化功耗。将可以推迟的操作尽量推迟到设备充电状态并且连接Wi-Fi时进行,比如同步和备份工作。
2.定位
-
如果你的app只是需要快速确定一下用户的位置,最好用CLLocationManager的requestLocation (iOS9引入)方法。定位完成之后会自动让硬件断电。
-
除非是在导航的时候,app大部分时间不需要实时更新,降低位置的更新频率。
-
尽量降低定位精度。iOS设备默认采用最高精度定位,如果你的app不是确实需要米级的位置信息,不要用最高精度(kCLLocationAccuracyBest)或10米左右的精度(kCLLocationAccuracyNearestTenMeters)。一般来说Core Location提供的精度比你设置的要好,比如你设置为3公里左右的精度,可能会收到100米左右的精度信息。
-
如果定位精度一直达不到设置的精度时,停止更新位置,稍后再试。
-
需要后台更新位置时,尽量把pausesLocationUpdatesAutomatically设为YES,如果用户不太可能移动的时候系统会自动暂停位置更新。
-
后台定位时延时更新位置。如果要做一个健身类的软件追踪用户徒步的距离,可以等用户移动一段距离或者过一段时间之后再更新位置,这样可以让系统优化能耗。
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性能。
-
减小写入数据。数据有变化再写文件,尽量把多个更改攒到一起一次性写入。如果只有几个字节的数据改变,不要把整个文件重新写入一次。如果你的app经常要修改大文件里很少的内容,可以考虑用数据库存储这些数据。
-
避免访问存储频度太高。如果app要存储状态信息,要等到状态信息有变化时再写入。尽量分批修改,不要频繁地写入这些小变动。
-
尽量顺序读写数据。在文件中跳转位置会消耗一些时间。
-
尽量从文件读写大数据块,一次读取太多数据可能会引发一些问题。比如,读取一个32M文件的全部内容可能会在读取完成前触发内容分页。
-
读写大量重要数据时,考虑用dispatch_io,其提供了基于GCD的异步操作文件I/O的API。用dispatch_io系统会优化磁盘访问。
-
如果你的数据由随机访问的结构化内容组成,建议将其存储在数据库中,可以使用SQLite或Core Data访问。特别是需要操作的内容可能增长到超过几兆的时候。
-
了解系统如何缓存文件、如何优化缓存的使用。如果你不打算多次引用某些数据,不要自己缓存数据。
4.GPU
-
减少app使用的视图数量。
-
少用运算获得圆角,不论view.maskToBounds还是layer.clipToBounds都会有很大的资源开销.
-
尽量少用透明或半透明,会产生额外的运算.
-
执行动画时不要修改帧率。比如,你的app帧率是60fps,整个动画就保持这个帧率不要变。
-
视频播放时,app尽量不要在全屏视频上添加额外的图层(即使是隐藏的图层)
5.优化通知
-
尽量用本地通知(local notification),如果你的app不依赖外部数据,而是需要基于时间的通知,应该用本地通知,可以让设备的网络硬件休息一下。
-
远程推送有两个级别,一个是立即推送,另一个是针对功耗优化过的延时推送。如果不是真的需要即时推送,尽量使用延时推送。
五、总结
耗电量分析是应用开发中很难的课题,也是衡量性能的重要指标,做好电量优化,可以大幅度提升用户体验,在实际开发过程中,电量消耗往往是一个综合的结果,小到日常的代码习惯,积少成多,大到网络的乱用、不合理的网络超时、不合理的定位使用、不合理的CPU使用,都会带来能耗的过多消耗,而这些问题仅仅会影响电量,还会影响用户体验,而对于这一个很多因素综合起来的结果,我们需要提高日常开发的代码质量,了解不同实现方式的差异点,优化页面卡顿,优化网络使用,优化GPS使用等等,只有综合这些因素,最终获得较好的用户体验。
在做耗电量分析的时候,首先要清楚耗电量较大的点,比如:网络、定位、CPU、GPU,从这些点来入手分析,再详细分析每个点,细分每个点中的一些细节的影响,比如:网络中可能会存在导致耗电量过高的因素,我们可以使用哪些优化方法,同时根据我们的需求特点,怎么来优化,最终找到可优化点的,找到解决方案,来优化耗电量。
在优化点寻找的过程中,我们首先可以使用Energy Impact来实时分析,各个维度指标是否有问题,占比是否合理,然后在通过Time Profiler
、Network Profiler
、Location Profiler
等工具对各项指标进行详细分析,寻找优化点。
其次我们可以使用Energy Log来横向对比各个维度的数据,来分析各个维度对总功耗的影响,比如:wifi数据传输和4G数据传输时,耗电量的对比,打开蓝牙和未打开蓝牙,能耗数据的对比,查看各个维度对能耗消耗影响的权重。也可以进行各种能耗数据的对比分析,以及优化前后的能耗数据对比,获取最终的优化效果。
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)