Android 性能优化方法论【总结篇】

news2024/9/22 13:34:31

作为一位多年长期做性能优化的开发者,在这篇文章中对性能优化的方法论做一些总结,以供大家借鉴。

性能优化的本质

首先,我先介绍一下性能优化的本质。我对其本质的认知是这样的:性能优化的本质是合理且充分的使用硬件资源,让程序的表现更好,并且程序表现更好的目的则是为了获取更多来自客户的留存,使用时长,口碑、利润等收益。

所以基于本质来思考,性能优化最重要的两件事情:

  1. 合理且充分的使用硬件资源

  2. 让程序表现更好,并取得收益

下面讲一下这两件事情。

合理且充分的使用硬件资源

充分表示能将硬件的资源充分发挥出来,但充分不一定是合理的,比如我们一下子打了几百个线程,cpu 被充分发挥了,但是并不合理,所以合理表示所发挥出来的硬件资源能给程序表现有正向的作用。

硬件资源包括:CPU,内存,硬盘,电量,流量(不属于硬件资源,不过也归于需要合理使用的资源之一)等等。

下面举几个合理且充分的使用硬件资源的例子:

  1. CPU 资源的使用率高,但并不是过载的状态,并且 cpu 资源主要为当前场景所使用,而不是被全业务所分散消耗。比如我们优化页面打开速度,速度和 cpu 有很大的关系,那么我们首先要确保 cpu 被充分发挥出来了,我们可以使用多线程、页面打开前提前预加载等策略,来发挥手机的 cpu。但是在打开页面的时候,我们要合理的确保 cpu 资源主要被打开页面相关的逻辑所使用,比如组件创建,数据获取,页面渲染等等,至于其他和当前打开页面场景联系较少的逻辑,比如周期任务,监控,或者一些预加载等等都可以关闭或者延迟,以此减少非相关任务对 cpu 的消耗,

  2. 内存资源缓使用充分,并且又能将 OOM 等异常控制在合理范围内。比如我们做内存优化,内存优化并不是越少越好,相反内存占用多可能让程序更快,但是内存占用也不能太高,所以我们可以根据不同档次机型的 OOM 率,将内存的占用控制在充分使用并且合理的状态,低端机上,通过功能降级等优化,减少内存的使用,高端机上,则可以适当提升内存的占用,让程序表现的更好。

  3. ……

让程序表现更好,并取得收益

我们有很多直接的指标来度量我性能优化取得的收益,比如做内存优化可以用 pss,java 内存占用,native 内存占用等等;做速度优化,可以用启动速度,页面打开速度;做卡顿优化,这用帧率等等。掌握这些指标很重要,我们需要知道如何能正确并且低开销的监控这些指标数据。

除了上面的直接指标外,我们还需要了解性能优化的最终体现指标,用户留存率,使用时长,转换率,好评率等指标。有时候,这些指标才是最终度量我们性能优化成果的数据,比如我们做内存优化,pss 降低了 100 M,但仅仅只是内存占用少了 100M 并没有太大的收益,如果这个 100M 体现在对应用的存活时间,转化率的提升上,那这 100 M 的优化就是值得的,我们再向上报告我们产出时,也更容易获得认可。

如何做好性能优化

讲完了性能优化的本质,我再讲讲如何做好性能优化。我主要从下面这三个方面来讲解

  1. 知识储备
  2. 思考的角度和方式
  3. 形成完整的闭环

知识储备

想要做好性能优化,特别是原创性、或者完善并且体系的、或者效果很好的优化,不是我们从网上看一些文章然后模仿一下就能进行,需要我们有比较扎实的知识储备,然后基于这些知识储备,通过深入思考,去分析我们的应用,寻找优化点。我依然举一些例子,来说明硬件层面,系统层面和软件层面的知识对我们做好性能优化的帮助。

硬件层面

在硬件层面,我们需要处理器的体系结构,存储器的层次结构有一定的了解。如果我们如果不知道 cpu 由几个核组成,哪些是大核,哪些是小核,我们就不会想到将核心线程绑定大核来提升性能的优化方案;如果我们不了解存储结构中寄存器,高速缓存,主存的设计,我们就没法针对这一特效来提升性能,比如将核心数据尽量放在高速缓存中就能提升不少速度相关的性能。

系统层面

对操作系统的熟悉和了解,也是帮助我们做好性能优化不可缺少的知识。我在这里列一下系统层面需要掌握的知识,但不是全的,Linux的知识包括进行管理和调度,内存管理,虚拟内存,锁,IPC通信等。Android系统的知识包括虚拟机,核心服务如ams,wms等等,渲染,以及一些核心流程,如启动,打开activity,安装等等。

如果我们不了解Linux系统的进程调度系统,我们就没法充分利用进程优先来帮助我们提升性能;如果我们不熟悉 Android 的虚拟机,那么围绕这虚拟机一些相关的优化,比如 oom 优化,或者是 gc 优化等等都无法很好的开展。

软件层面

软件层面就是我们自己所开发的 App,在性能优化中,我们需要对自己所开发的应用尽可能得熟悉。比如我们需要知道自己所开发的 App 有哪些线程,都是干嘛的,这些线程的 cpu 消耗情况,内存占用多少,都是哪些业务占用的,缓存命中率多少等等。我们需要知道自己所开发的 App 有哪些业务,这些使用都是干嘛的,使用率多少,对资源的消耗情况等等。

除了上面提到的三个层面的知识,想要深入做好性能优化,还需要掌握更多的知识,比如汇编,编译器、编程语言、逆向等等知识。比如用c++ 写代码就比用java写代码运行更快,我们可以通过将一些业务替换成 c++ 来提高性能;比如编译期间的内联,无用代码消除等优化能减少包体积;逆向在性能优化上的用处也非常大,通过逆向我们可以修改系统的逻辑,让程序表现的更好。

可以看到,想要做好性能优化,需要庞大的知识储备,所以性能优化是很能体现开发者技术深度和广度的,这也是面试时,一定会问性能优化相关的知识的原因。这是知识储备不是一下就能形成的,需要我们慢慢的进行学习和积累。

思考的角度及方式

讲完了知识储备,再讲讲思考的角度和方式。需要注意它和知识储备没有先后关系,并不是说要有了足够的技术知识后才能开始考虑如何思考。思考的角度和方式体现在我们开发的所有生命周期中,即使是新入门的开发,也可以锻炼自己从不同的角度和方式去进行思考。下面就聊一聊我在做性能优化的过程中,在思考的角度和方式上的一些认知。为了让大家能更形象的理解,我就都以启动优化来讲解。

思考角度

我这里主要通过应用层,系统词,硬件层这三个角度来介绍我对启动速度优化的思考。

应用层

做启动速度优化时,如果从应用层来考虑,我会基于业务的维度考虑所加载的业务的使用率,必要性等等,然后制定优先级,在启动的时候只加载首屏使用,或者使用率高的业务。所以接着我就可以设计启动框架用来管理任务,启动框架要设计好优先级,并且能对这些初始化的任务有使用率或者其他性能方面的统计,比如这些任务初始化后,被使用率的概率是多少,又或者初始化之后,对业务的表现提升提现在哪,帮助有多大。

从应用层的思考主要是基于对业务的管控或者对业务进行优化来提升性能。

系统层

以及系统层来考虑启动优化也有很多点,比如线程和线程优先级维度,在启动过程中,如何控制好线程数量,如何提高主线程的优先级,如何减少启动过程中不相关的线程,比如 gc 线程等等。

硬件层

从硬件层来考虑启动优化,我们可以从 cpu 的利用率,高速缓存cache的命中率等维度来考虑优化。

除了上面提到的这几个角度,我们还可以有更多角度。比如跳出本设备之外来思考,是否可以用其他的设备帮助我们加速启动。google play 就有类似的优化,gp会上传一些其他机器已经编译好的机器码,然后相同的设备下载这个应用时,也会带着这些编译好的机器码一起下载。还有很常用的服务端渲染技术,也是让服务端线渲染好界面,然后直接暂时静态模块来提升页面打开速度;又或者站在用户的角度去思考,想一想到底什么样的优化对用户感知上是有好处的,比如有时候我们再做启动或者页面打开速度优化,会给用户一个假的静态页面让用户感知已经打开了,然后再去绑定真实的数据。

做性能优化时,考虑的角度多一些,全面一些,能帮助我们想出更多的优化方案。

思考方式

除了锻炼我们站在不同的角度思考问题,我们还可以锻炼自己思考问题的方式,这里介绍自上而下和自下而上两种思考方式。

自上而下

我们做启动优化,自上而下的优化思路可能是直接从启动出发,然后分析启动过程中的链路,然后寻找耗时函数,将耗时函数放子线程或者懒加载处理,但是这种方式会导致优化做的不全面。比如将耗时的任务都放在子线程,我们再高端机上速度确实变快了,但是在低端机上,可能会降低了启动速度,因为低端机的 cpu 很差,线程一多,导致 cpu 满载,主线程反而获取不到运行时间。其次,如果从上层来看,一个函数执行耗时久可能并不是这个函数的问题,也可能是因为该函数长时间没有获取到 cpu 时间。

自上而下的思考很容易让我们忽略本质,导致优化的效果不明显或者不完整。

自下而上

自下而上思考就是从底层开始思考,还是以启动优化为例子,自下而上的思考就不是直接分析启动链路,寻找慢函数,而是直接想着如何在启动过程中合理且充分的使用 cpu 资源,这个时候我们的方案就很多了,比如我们可能会想到不同的机型 cpu 能力是不一样的,所以我们会针对高端机和低端机来分别优化,高端机上,我们想办法让cpu利用率更高,低端机上想办法避免 cpu 的超载,同时配合慢函数,线程,锁等知识进行优化,就能制定一套体系并且完整的启动优化方案。

完整的闭环

上面讲的都是如何进行优化,优化很重要,但并不是全部,在实际的性能优化中,我们需要做的有监控,优化,防劣化,数据收益收集等等,这些部分都做好才能形成一个完整的闭环。我一一讲一下这几个部分:

  • 监控:完整的监控应用中各项性能的指标,仅仅有指标监控是不够的,我们还需要尽量做归因的监控。比如内存监控,我们不仅仅要监控我们应用的内存指标,还可以还要能监控到各个业务的内存使用占比,大集合,大图片,大对象等等归因项。并且我们的监控同样要基于性能考虑去设计。完整的监控能让我们更高效的发现和解决异常。

  • 优化:优化就是前面提到的,合理且充分的使用硬件资源,让程序的表现更好。

  • 防劣化:防劣化也是有很多事情可以做的,包括建立完善的线下性能测试,线上监控的报警等。比如内存,我们可以在线下每天通过monkey跑内存泄露并提前治理,这就是防劣化。

  • 数据收益收集。学会用好A/B测试,学会关注核心价值的指标。比如我们做内存优化,一味的追求降低应用内存的占用并不是最优,内存占用的多,可能会让我们的程序运行更快,用户体验更好,所以我们需要结合崩溃率,留存等等这种体验核心价值的指标,来确定内存到底要不要继续进行优化或者优化到多少。

小结

上面就是我在多年的性能优化经验中总结出来的认知及方法论。只有了解了这些方法论,我们才能在进行性能优化时,如鱼得水,游刃有余。


为了帮助到大家更好的掌握性能优化相关知识点,这准备了 性能优化知识点汇总和Android 性能监控框架 的学习文档,中间记录了 启动优化、内存优化、UI优化……等知识点,感兴趣的可以看下这《Android 性能调优系列学习手册》:https://0a.fit/dNHYY

内存优化

UI优化

电量优化

网络优化

Bitmap优化与图片加载优化


感兴趣的可以看下这《Android 性能调优系列学习手册》:https://0a.fit/dNHYY

多线程并发优化与数据传输优化

安装包优化与服务优化


启动优化

Android 性能监控框架 Matrix

更多Android 知识点可参考

Android 性能调优系列https://0a.fit/dNHYY

Android 车载学习指南https://0a.fit/jdVoy

Android Framework核心知识点笔记https://0a.fit/acnLL

Android 八大知识体系https://0a.fit/mieWJ

Android 中高级面试题锦https://0a.fit/YXwVq

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/32939.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

分享感恩节联系客户话术

看了一眼在手边的日历,发现今天是11月24日,一年一度的感恩节又到了,不得不感叹时间过得真快,每年十一月的第四个星期四是感恩节。 随着各国多元文化的发展,感恩节也越来越被世界各地传颂,多少都会有一些影…

WANLSHOP 直播短视频种草多用户电商系统源码自营+多商户+多终端(H5+小程序+APP)

WANLSHOP高级版 可用于自营外包项目(多主体)、 可用于外包定制开发项目、 提供开源源码,私有化部署、一款基于 FastAdmin Uni-APP 开发的 多终端(H5移动端、APP、微信小程序、微信公众号)、多用户商城系统拥有多种运营模式B2B2C/B2C&#xf…

python安装依赖库

一、安装pip 1、打开终端,输入: pip3 install tushare -i https://pypi.douban.com/simple 2、验证是否安装成功 打开终端,输入:pip3 出现以上页面,则安装成功 二、安装flask 1、打开终端,输入&…

mybatis-plus学习笔记

文章目录1 简介2 初始化项目2.1引入pom2.2 引入lombok插件2.3 配置信息2.4 创建实体类2.5 创建mapper2.6 配置注解MapperScan2.7 编写测试类2.8 配置MyBatis日志3 测试基本的CRUD3.1 新增3.2 查询3.3 修改3.4 删除4 自定义动态sql5 Service 层使用mybatis-plus方法5.1 service层…

使用hive进行大数据项目分析

目录 一、首先要创建表:在txt记事本中先输入创建语句备用,创建class1~class5的表。 二、启动hadoop集群,MySQL,hive。 三、创建数据库zhh,用户为zhh,之后将之前写在txt记事本里的创建表class1~class5的命…

浅谈企业信息化安全建设中的三大误区

伴随着信息化的深度建设与应用,与之相伴的信息安全事件也层出不穷!很多企业开始关注信息安全问题、关注信息安全建设,大家的共识已经达到前所未有的高度。 虽然许多的企业虽然认识到信息安全的重要性,在实际实施过程中却又无从下…

【附源码】计算机毕业设计JAVA亦心化妆品网站

【附源码】计算机毕业设计JAVA亦心化妆品网站 目运行 环境项配置: Jdk1.8 Tomcat8.5 Mysql HBuilderX(Webstorm也行) Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。 项目技术: JAVA myba…

【软件测试】我们测试人搭上元宇宙的列车,测试一直在进军......

目录:导读前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结(尾部小惊喜)前言 虚拟宇宙&#xff0…

微信抽奖小程序开发_分享微信抽奖小程序制作的步骤

各位商家在节日期间做活动的时候,都希望用更少的费用去或者更好的宣传和推广的效果。比较常见的就是抽奖活动小程序。无须玩家下载,通过微信扫码或者指定入口就可以参与。 方便,效果又好。 那么,性价比高的抽奖活动小程序怎么做&#xff1f…

使用 MITRE ATTCK 技术保护您的 Active Directory安全

Active Directory (AD域)保存着企业的敏感数据,例如用户凭据、员工的个人信息、安全权限等。正因为如此,AD域很容易成为网络攻击者的目标。恶意攻击者不断升级新的攻击策略,使企业保护AD域安全成为一项挑战。这就是为什么每个企业都必须制定网…

scratch猫捉老鼠 电子学会图形化编程scratch等级考试一级真题和答案解析2022年9月

目录 scratch猫捉老鼠 一、题目要求 1、准备工作 2、功能实现 二、案例分析

【U8+】用友U8成本管理模块下,定额分配标准中无法取到新增存货的数据。

【问题描述】 用友U8,新增存货后, 在【成本管理】模块下,操作【定额分配标准】取数后,无法取到新增存货数据。 【解决方案】 由于没有过多的研究过用友U8的成本管理模块, 以下过程是在处理该问题时,整理的…

java发送邮件

前言 借用hutool工具&#xff0c;实现多账号发送邮件 相关实现 maven依赖 Hutool对所有第三方都是可选依赖&#xff0c;因此在使用MailUtil时需要自行引入第三方依赖。 <dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</arti…

机器学习笔记之高斯网络(一)基本介绍

机器学习笔记之高斯网络——基本介绍引言回顾&#xff1a;条件独立性概率图模型高斯网络高斯网络介绍高斯网络的条件独立性随机变量之间的边缘独立随机变量之间的条件独立引言 本节将介绍高斯网络 回顾&#xff1a; 条件独立性 在概率图模型——背景介绍中介绍了条件独立性…

Dissertation写作常用的研究方法

英文毕业论文的撰写&#xff0c;有很多值得注意的重要因素&#xff0c;而研究方法的选择无疑是最重要的内容之一。留学毕业论文不同于平常的研究性论文&#xff0c;其难度和复杂程度要大得多&#xff1b;同时&#xff0c;导师对于留学毕业论文的要求又非常严格。因此写好一篇优…

[附源码]SSM计算机毕业设计教务系统JAVA

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

跨境电商卖家必知的【圣诞节营销】终极指南(二)

关键词&#xff1a;圣诞节营销、跨境电商卖家 不知不觉又到了年底&#xff0c;而对于跨境电商来说也是非常重要的一段促销时期&#xff0c;上一篇文章我们探讨了一些圣诞节营销的创意方法&#xff0c;今天我们将告诉您完整的圣诞节营销指南。 1. 闪购和 FOMO 限时抢购是您的电…

ImmunoChemistry艾美捷基本细胞毒性试验试剂盒测定方案

ImmunoChemistry艾美捷基本细胞毒性试验试剂盒是一种通过流式细胞仪测定细胞毒性的单管双色试验。该试验使用绿色荧光细胞染色剂CFSE标记靶细胞&#xff0c;使用红色活/死活性染料7-AAD识别细胞毒性试验样品中存在的死细胞。使用流式细胞仪分析结果。 细胞裂解活性是清除细胞内…

D-012 时钟硬件电路设计

时钟硬件电路设计1 简介2 晶振电路中电容的选择3 时钟电路设计要点4 晶振选型5 电路实战1 简介 晶振时数字电路的心脏&#xff0c;数字电路需要一个稳定的工作时钟信号&#xff0c;时钟电路时硬件电路设计中不可或缺的一个重要内容。晶振一般指晶体振荡器。而在封装内部添加 I…

Shell脚本学习指南(四)——管道的神奇魔力

文章目录前言从结构化文本文件中提取数据针对Web的结构型数据文字解谜好帮手单词列表标签列表前言 当你在UNIX里对付文字处理作业时&#xff0c;必须谨记一个UNIX工具使用原则就是&#xff1a;想清楚这个问题该如何划分为更简单的工作&#xff0c;每个部分是不是已有现成的工具…