看看别家的APP性能优秀不?

栏目: IOS · 发布时间: 4年前

内容简介:APP的性能大家应该都比较关注,那么咱们的自己APP性能如何呢?如何在拿不到源码的情况下去调试第三方应用的性能呢?下面我就简单实践一下。就以比较著名的今日头条和贝壳找房为例吧!大家看看自己的APP和他们还有多少差距。下面我们对这个指标以2个APP进行性能分析,分别是贝壳找房2.6.1版本、今日头条7.2.2版本。手机我们使用12.2系统的iPhoneX。我们借助于Instruments中的Activity Monitor工具进行分析。首先我们去拿到这几个ipa的脱壳包(这里可以借鉴这两篇文章,传送门一->点

APP的性能大家应该都比较关注,那么咱们的自己APP性能如何呢?如何在拿不到源码的情况下去调试第三方应用的性能呢?下面我就简单实践一下。就以比较著名的今日头条和贝壳找房为例吧!大家看看自己的APP和他们还有多少差距。

二、分析启动时和启动后的cpu和内存占用

下面我们对这个指标以2个APP进行性能分析,分别是贝壳找房2.6.1版本、今日头条7.2.2版本。手机我们使用12.2系统的iPhoneX。我们借助于Instruments中的Activity Monitor工具进行分析。首先我们去拿到这几个ipa的脱壳包(这里可以借鉴这两篇文章,传送门一->点击我, 传送门二->点击我;或者可以去越狱市场直接下载脱壳好的包),脱壳后使用development的证书进行重签名(可以参考:传送门->点击我)。然后我们将这两个包安装到手机中去。

如图:

看看别家的APP性能优秀不?

以下我们分别对这2个APP测试APP启动前5秒的CPU峰值以及对应的内存占用和启动后某一平稳时段的CPU占用以及对应的内存。

2.1

先看今日头条的数据:

如图:

看看别家的APP性能优秀不?

今日头条在前5秒的CPU峰值达到了148.1%,此时的内存占用是63.66M

然后我们再看看启动后的平稳数据

如图:

看看别家的APP性能优秀不?

CPU是3.9%,此时的内存占用是102.06M

2.2

我们再看贝壳找房的数据:

如图:

看看别家的APP性能优秀不?

贝壳找房在前5秒的CPU峰值达到了116.4%,此时的内存占用是77.30M

然后我们再看看启动后的平稳数据

如图:

看看别家的APP性能优秀不?

CPU是2.9%,此时的内存占用是77.02M

从以上数据看,两个APP的突发峰值都还好,平峰比较稳定,大家可以对比看下自己的APP是否和他们差不多,我们再看下一个指标,APP启动时间。

三、分析APP启动时常

下面我们使用 MonkeyDev (传送门-> 点击我 ) 工具将上面的那两个包运行起来,在Environment Variables中加入DYLD_PRINT_STATISTICS变量,得到Total pre-main time。我们对每个APP分别测量3次,取平均值。

如图:

看看别家的APP性能优秀不?

3.1

我们先看今日头条的3次测量数据

第一次:

看看别家的APP性能优秀不?

第二次:

看看别家的APP性能优秀不?

第三次:

看看别家的APP性能优秀不?

得到最终今日头条的平均值是:1.3s

3.2

然后我们再看贝壳找房的3次数据

第一次:

看看别家的APP性能优秀不?

第二次:

看看别家的APP性能优秀不?

第三次:

看看别家的APP性能优秀不?

得到最终贝壳找房的平均值是:954.66ms

从以上数据分析,各个APP之间的pre-main之间耗费的时间差别并不多,我们看下各个内容的含义。

  • dylib loading time
    载入动态库,这个过程中,会去装载app使用的动态库,而每一个动态库有它自己的依赖关系,所以会消耗时间去查找和读取。对于Apple提供的的系统动态库,做了高度的优化。而对于开发者定义导入的动态库,则需要在花费更多的时间。Apple官方建议尽量少的使用自定义的动态库,或者考虑合并多个动态库,其中一个建议是当大于6个的时候,则需要考虑合并它们
  • rebase/binding time

    重构和绑定,rebase会修正调整处理图像的指针,并且会设置指向绑定(binding)外部的图像指针。所以为了加快rebase/binding,则需要更少的做指针修复。当你的app当中有太多的Objective-C的类,方法选择器,和类别会增加这一部分的启动时间。有一个数据当大于20000个时候,会增加800ms的时间。另一点:当你的app中使用了很少的C++的虚拟函数,使用Swift会更加高效

  • ObjC setup time

    在Objective-C的运行时(runtime),需要对类(class),类别(category)进行注册,以及选择器的分配,所以参照rebase/binding time,尽量减少类的数量,可以达到减少这一部分的时间

  • initializer time

    这一份指代的是执行+initialize方法的时间。如果你执行了+load方法(不建议),尽量使用+initialize代替。

  • slowest intializers

    这个列出的是最慢的几个dylib文件。

从以上数据来看,他们大致的耗时操作都差不多,需要从以上几点进行一下优化。不过我看来优化启动的时间应该从pre-main之后入手,测试main到第一个viewcontroller的viewDidAppear的时间。

四、分析APP第一个控制器的启动时间

下面我以贝壳找房进行详细描述,用FLEXible获取贝壳找房的首页控制器名称

如图:

看看别家的APP性能优秀不?

然后我们注入如下代码:获取首页控制器的viewDidLoad到viewDidAppear的执行时间

CHDeclareClass(LJHomePageViewController)

CHOptimizedMethod1(self, void, LJHomePageViewController, viewDidAppear, BOOL, animated)
{
    CHSuper1(LJHomePageViewController, viewDidAppear, animated);
    NSLog(@"第一个视图完毕");
    // 得到加载时间
    NSTimeInterval duration = [[NSDate date] timeIntervalSinceDate:self.testDate];
    NSLog(@":blush::blush::blush::blush::blush::blush::blush::blush::blush::blush::blush::blush:%g", duration);
}

CHOptimizedMethod0(self, void, LJHomePageViewController, viewDidLoad)
{
    CHSuper0(LJHomePageViewController, viewDidLoad);
    YYFPSLabel *fpsLabel = [YYFPSLabel new];
    fpsLabel.frame = CGRectMake(180, 200, 120, 30);
    [fpsLabel sizeToFit];
    [[UIApplication sharedApplication].delegate.window addSubview:fpsLabel];

    NSDate *date = [NSDate date];
    // 保存开始时间
    self.testDate = date;
}

////add new property
CHPropertyRetainNonatomic(LJHomePageViewController, NSDate*, testDate, setTestDate);

CHConstructor{
    CHLoadLateClass(LJHomePageViewController);
    CHClassHook0(LJHomePageViewController, viewDidLoad);
    CHClassHook1(LJHomePageViewController, viewDidAppear);

    CHHook0(LJHomePageViewController, testDate);
    CHHook1(LJHomePageViewController, setTestDate);

}

看看别家的APP性能优秀不?

可以看到他第一个控制器的时间约为0.24s,当然网络请求后的渲染时间此处是没有统计的,有兴趣的大家可以再hook网络那部分。

五、分析APP主要列表的FPS

这里我以今日头条为例子,使用FLEXible获取今日头条的主页面,然后分别对各个主页面的viewDidLoad方法进行Hook,然后在这里加入YYFPSLabel。这里直接对APPDelegate进行Hook也可以。

如图:

看看别家的APP性能优秀不?

以下是hook的代码:

@interface TTFeedCollectionViewController
- (void)viewDidLoad;
@end

CHDeclareClass(TTFeedCollectionViewController)

CHOptimizedMethod0(self, void, TTFeedCollectionViewController, viewDidLoad)
{
    CHSuper0(TTFeedCollectionViewController, viewDidLoad);
    YYFPSLabel *fpsLabel = [YYFPSLabel new];
    fpsLabel.frame = CGRectMake(180, 200, 50, 30);
    [fpsLabel sizeToFit];
    [[UIApplication sharedApplication].delegate.window addSubview:fpsLabel];
}

CHConstructor{
    CHLoadLateClass(TTFeedCollectionViewController);
    CHClassHook0(TTFeedCollectionViewController, viewDidLoad);
}

然后我们就可以看到所有页面的帧率

如图:

看看别家的APP性能优秀不?

此处页面稳定后的帧率是接近60,可以看出今日头条优化的还是可以的。

六、总结:

以上是以今日头条和贝壳找房进行了下实践,大家感兴趣可以多试试,然后对比自己的应用,看看有没有需要提高的。另外可以借鉴逆向的思维,去调试一些东西,挖掘和大厂APP之间的差距。这就是这篇文章的初衷。

打赏作者

如果这篇文章帮助了你,可以请作者喝罐可乐,以此激励作者创作更多!

去打赏

支持: 微信支付 支付宝

您的支持将鼓励我继续创作!

看看别家的APP性能优秀不?

[微信] 扫描二维码打赏

看看别家的APP性能优秀不?

[支付宝] 扫描二维码打赏


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Essential ActionScript 3.0

Essential ActionScript 3.0

Colin Moock / Adobe Dev Library / June 22, 2007 / $34.64

ActionScript 3.0 is a huge upgrade to Flash's programming language. The enhancements to ActionScript's performance, feature set, ease of use, cleanliness, and sophistication are considerable. Essentia......一起来看看 《Essential ActionScript 3.0》 这本书的介绍吧!

Markdown 在线编辑器
Markdown 在线编辑器

Markdown 在线编辑器

UNIX 时间戳转换
UNIX 时间戳转换

UNIX 时间戳转换

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具