能耗
-
CPU
不论用户是否正在直接使用,CPU都是应用所使用的主要硬件,在后台操作和处理推送通知时,应用仍会消耗CPU资源
计算量的能耗:
- 对数据的处理
- 待处理数据大小
- 处理数据的算法和数据结构
- 执行更新的次数,尤其是在数据更新后,触发应用的状态或者UI进行更新
处理消耗的最佳实践
能耗优化:
- 针对不同的情况选择最优的算法
- 如果应用从服务器接收数据,尽量减少需要做客户端进行的处理
- 优化静态编译处理(AOT)动态编译处理(JIT)
- 分析电量消耗,找到高耗能的区域并降低耗能
- 网络
避免在没有链接Wi-Fi的情况下进行高带宽消耗的操作,比如视频流。蜂窝无线网络对电量的消耗远大于Wi-Fi信号,根源在于LTE设备基于多输入,多输出技术,使用多个并发信号以维护两端的LTE链接
- 在进行任何网络请求操作之前,先检查和事的网络链接是否可用。
- 持续监视网络的可用性,并在链接状态发生变化时给予适当的反馈。
- 定位管理器和GPS
使用GPS计算坐标需要确定两点信息:
时间锁:每个GPS卫星每毫米广播唯一一个1023位随机数,因而数据传播速率1.024Mbit/s。GSP的接受芯片必须正确的与卫星的时间锁对齐。
频率锁:GPS接收器必须计算由接收器与卫星的相对运动导致的多普勒偏差带来的信号误差。
所以:不断的计算坐标会使用CPU和GPS的硬件资源,迅速的消耗电池电量。
- 屏幕
- 动画:明智的使用动画是一个被抛弃的概念,当然在应用进入后台时,也是需要立即暂停或者关闭动画,换到前台时在恢复或开启动画。
- 视频播放:通过响应应用的通知来释放和获取锁。
- 多屏幕:如果正在播放电影或运行动画,你可以将它们从设备的屏幕挪到屏幕外部, 在设备的屏幕上保留最基本的控制,这样可以减少设备上的屏幕更新,延长电池寿命。
- 其他硬件
- 蓝牙
- 相机
- 扬声器
- 麦克风
硬件的使用,基本规则是一样的:只有在前台需要时才与硬件交互,否则应该处理停止状态。扬声器和无线蓝牙可能例外
- 电池电量
- 最小化硬件使用
- 在进行密集任务前,检查电池电量和充电状态
- 在电量低时,提示用户是否确定继续执行任务
- 或提供设置的选项,允许用户定义电量的阀值
/**
设置进程的最小电量
@param minLevel f最小阀值
@return YES:可继续执行,NO:不可继续执行
*/
- (BOOL)shouldProceedWithMiniLevel:(NSUInteger)minLevel{
UIDevice *device = [UIDevice currentDevice];
device.batteryMonitoringEnabled = YES;
UIDeviceBatteryState state = device.batteryState;
if (state == UIDeviceBatteryStateCharging || state == UIDeviceBatteryStateFull) {
return YES;
}
NSUInteger batteryLevel = (NSUInteger)(device.batteryLevel * 100);
if (batteryLevel >= minLevel) {
return YES;
}
return NO;
}
/**
CPU的使用率
@return 已使用的CPU
*/
-(CGFloat)getAPPCPUUsage{
kern_return_t kr;
task_info_data_t tinfo;
mach_msg_type_number_t task_info_count;
task_info_count = TASK_INFO_MAX;
kr = task_info(mach_task_self(), TASK_BASIC_INFO, (task_info_t)tinfo, &task_info_count);
if (kr != KERN_SUCCESS) {
return -1;
}
task_basic_info_t basic_info;
thread_array_t thread_list;
mach_msg_type_number_t thread_count;
thread_info_data_t thinfo;
mach_msg_type_number_t thread_info_count;
thread_basic_info_t basic_info_th;
uint32_t stat_thread = 0; // Mach threads
basic_info = (task_basic_info_t)tinfo;
// get threads in the task
kr = task_threads(mach_task_self(), &thread_list, &thread_count);
if (kr != KERN_SUCCESS) {
return -1;
}
if (thread_count > 0)
stat_thread += thread_count;
long tot_sec = 0;
long tot_usec = 0;
float tot_cpu = 0;
int j;
for (j = 0; j < (int)thread_count; j++)
{
thread_info_count = THREAD_INFO_MAX;
kr = thread_info(thread_list[j], THREAD_BASIC_INFO,
(thread_info_t)thinfo, &thread_info_count);
if (kr != KERN_SUCCESS) {
return -1;
}
basic_info_th = (thread_basic_info_t)thinfo;
if (!(basic_info_th->flags & TH_FLAGS_IDLE)) {
tot_sec = tot_sec + basic_info_th->user_time.seconds + basic_info_th->system_time.seconds;
tot_usec = tot_usec + basic_info_th->user_time.microseconds + basic_info_th->system_time.microseconds;
tot_cpu = tot_cpu + basic_info_th->cpu_usage / (float)TH_USAGE_SCALE * 100.0;
}
} // for each thread
kr = vm_deallocate(mach_task_self(), (vm_offset_t)thread_list, thread_count * sizeof(thread_t));
assert(kr == KERN_SUCCESS);
return tot_cpu;
}
网友评论