前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >iOS启动优化

iOS启动优化

作者头像
玖柒的小窝
修改2021-11-01 10:51:51
6210
修改2021-11-01 10:51:51
举报
文章被收录于专栏:各类技术文章~各类技术文章~

1. 什么是启动?

启动类型

image.png
image.png

启动三种类型:冷启动 热启动 重启

启动阶段

image.png
image.png
1.1 System Inteface Dyld3
image.png
image.png
image.png
image.png
1.2 System Inteface libSystem Init
image.png
image.png
2. Runtime Init Static Runtime Initialization
image.png
image.png
image.png
image.png
3. UIKit Init
image.png
image.png
image.png
image.png
4. Appliciation Initializtion
image.png
image.png
image.png
image.png
5. Initial Frame Render
image.png
image.png
image.png
image.png
6. Extend
image.png
image.png
image.png
image.png

2. 如何正确测量?

image.png
image.png

1. XCTest

image.png
image.png

2. Use Instruments

image.png
image.png
1. Minimize
image.png
image.png
2. Prioritize work
image.png
image.png
3. Optimize
image.png
image.png
image.png
image.png
image.png
image.png
image.png
image.png
image.png
image.png

二进制重排

将启动时需要调用的函数放到一起 ( 比如 前10页中 ) 以尽可能减少 page fault , 达到优化目的 . 而这个做法就叫做 : 二进制重排 .

具体操作:

  • 如何检测 page fault : 首先我们要想看到优化效果 , 就应该知道如何查看 page fault , 以此来帮助我们查看优化前以及优化后的效果 .

打开link map File 添加order文件 工程配置

借助clang 官方文档 clang Tracing PC 跟踪PC指针

通过clang排列二进制

代码的二进制,代码的实现的二进制。

  1. 配置clang 插桩
  2. clang插桩的原理(只要添加了clang插桩的标记,那么便一起就会在所有方法函数block代码实现边缘添加一行代码。 执行回调函数。)
  3. 获取符号(函数调用栈,其实就是通过return/)
  4. 通过原子队列保存符号
  5. 解决天坑,仅拦截方法
  6. 符号去重,生成order文件
代码语言:javascript
复制
#import <libkern/OSAtomic.h>
#include <sanitizer/coverage_interface.h>
#include <dlfcn.h>

// 定义原子队列
static OSQueueHead sybmolList = OS_ATOMIC_QUEUE_INIT;
// 定义符号结构体
typedef struct {
    void *pc;
    void *next;
} SYNNode;
- (void)testSleep{
void __sanitizer_cov_trace_pc_guard_init(uint32_t *start,
                                                    uint32_t *stop) {
  static uint64_t N;  // Counter for the guards.
  if (start == stop || *start) return;  // Initialize only once.
  printf("INIT: %p %p\n", start, stop);
  for (uint32_t *x = start; x < stop; x++)
    *x = ++N;  // Guards should start from 1.
}

// 可以拦截一切的方法调用
void __sanitizer_cov_trace_pc_guard(uint32_t *guard) {
  if (!*guard) return;  // Duplicate the guard check.
  void *PC = __builtin_return_address(0);
    // 多线程访问数据的方法 线程安全
    // 创建结构体
    SYNNode * node = malloc(sizeof(SYNNode));
    *node = (SYNNode){PC,NULL};
    
    // 结构体入栈
    OSAtomicEnqueue(&sybmolList, node, offsetof(SYNNode, next));
}



- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    
    NSMutableArray<NSString *> *symbolNames = [NSMutableArray new];
    while(YES){
        SYNNode *node = OSAtomicDequeue(&sybmolList,  offsetof(SYNNode, next));
        if (node == NULL) {
            break;
        }
        Dl_info info;
        dladdr(node->pc, &info);
        NSString *name = @(info.dli_sname);
        
        // 给函数名称添加_
        BOOL isObjc = [name hasPrefix:@"+["] || [name hasPrefix:@"-["];
        NSString *symbolName = isObjc ? name :[@"_" stringByAppendingString:name];
        [symbolNames addObject:symbolName];
    }
    NSEnumerator *em = [symbolNames reverseObjectEnumerator];
    NSMutableArray *funcs = [NSMutableArray arrayWithCapacity:symbolNames.count];
    
    NSString *name;
    // 有序去重
    while (name = [em nextObject]) {
        if(![funcs containsObject:name]) {
            [funcs addObject:name];
        }
    }
    
    //去掉自己
    [funcs removeObject:[NSString stringWithFormat:@"%s",__func__]];
    
    // 写入文件
    // 转成字符串
    NSString * funcStr = [funcs componentsJoinedByString:@"\n"];
    NSString *filePath = [NSTemporaryDirectory() stringByAppendingPathComponent:@"caoliang.order"];
    
    // 转成二进制
    NSData *file = [funcStr dataUsingEncoding:NSUTF8StringEncoding];
    [[NSFileManager defaultManager] createFileAtPath:filePath contents:file attributes:nil];
    
    NSLog(@"%@",funcStr);
}
复制代码
  1. swift 符号覆盖

other Swift Flag 添加标记 -sanitize-coverage=func -sanitize=undefined

本文系转载,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文系转载前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 启动类型
  • 启动阶段
    • 1.1 System Inteface Dyld3
      • 1.2 System Inteface libSystem Init
        • 2. Runtime Init Static Runtime Initialization
          • 3. UIKit Init
            • 4. Appliciation Initializtion
              • 5. Initial Frame Render
                • 6. Extend
                • 2. 如何正确测量?
                  • 1. XCTest
                    • 2. Use Instruments
                      • 1. Minimize
                      • 2. Prioritize work
                      • 3. Optimize
                  • 二进制重排
                    • 通过clang排列二进制
                    领券
                    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档