为了提高应用的体验,我们需要对程序作出优化。难点不在如何做优化,而在找出优化的点。
优化常见的手段就是:
1 异步读写:图片,数据库,沙盒文件,plist等
2 异步处理数据:后台解析数据,异步计算UI高度,异步处理图片如圆角
3 缓存:保存处理后的数据(UI高度,lable高度),图片等
找出需要优化的地方,才是本文重点.
监控窗口,可移动位置
我们做一个浮窗,实时监控每一步操作的性能表现, 对卡顿点做记录并保存文件。
计算内存
#include <mach/mach.h>
#include <mach/task_info.h>
#include <sys/types.h>
#include <sys/sysctl.h>
- (vm_size_t)getUsedMemory
{
struct mach_task_basic_info info;
mach_msg_type_number_t size = MACH_TASK_BASIC_INFO_COUNT;
kern_return_t kerr = task_info(mach_task_self(), MACH_TASK_BASIC_INFO, (task_info_t)&info, &size);
return (kerr == KERN_SUCCESS) ? info.resident_size : 0; // size in bytes
}
计算CPU
- (float)getUsedCPU
{
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 < 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->system_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;
}
计算FPS
CADisplayLink *_fpsLink;
NSUInteger _count;
NSTimeInterval _lastTime;
float _fpsValue;
- (void)startFpsDisplayLink
{
if (!_fpsLink) {
_fpsLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(tick:)];
[_fpsLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes];
}
}
- (void)stopFpsDisplayLink
{
if(_fpsLink){
[_fpsLink invalidate];
_fpsLink = nil;
}
}
- (void)tick:(CADisplayLink *)displayLink
{
if (0 == _lastTime) {
_lastTime = displayLink.timestamp;
return;
}
_count ++;
NSTimeInterval delta = displayLink.timestamp - _lastTime;
if (delta < 1) {
return;
}
_fpsValue = _count / delta;
_lastTime = displayLink.timestamp;
_count = 0;
}
记录卡顿点,打印卡顿堆栈
可查看卡顿代码源码下载
https://github.com/FSilver/FWMonitor
FWMonitorView *view = [FWMonitorView monitor];
[[UIApplication sharedApplication].keyWindow addSubView:view];
只需两行代码,即可完成所有监控指标
网友评论