【Android】性能实践—编码优化与布局优化学习笔记

news/2024/11/14 9:25:12/

编码优化

使用场景

  1. 如果需要拼接字符串,优先使用StringBuffer和StringBuilder进行凭借,他们的性能优于直接用加号进行拼接,因为使用加号连接符会创建多余的对象
  2. 一般情况下使用基本数据类来代替封装数据类型(比如int优于Integer)
  3. 当返回一个String类型的数据时,如果明确知道返回后的字符串用于进行拼接操作,那么可以考虑返回StringBuffer,因为StringBuffer是一个对象的引用而String的话就是创建了一个短生命周期的临时对象
  4. 类似于第二条,基本数据类型数组也优于对象数据类型数组(a[]和b[]使用起来效率比c(a, b)[]高得多)

静态优于抽象

当我们只想调用某个对象的某个方法去实现一个功能的时候,可以将该方法设置为静态方法,因为调用静态方法可以不用创建对象,也可以使得调用速度提升。

class Utils {public static int add(int a, int b) {return a + b;}
}// 调用静态方法,不需要创建 Utils 的对象
int result = Utils.add(3, 5);

使用static和final修饰符

内存效率

  • static 关键字使变量成为类变量,而不是实例变量。这样,不管创建多少个类的实例,常量在内存中只存在一份,节省内存空间。
public class MyClass {public static final int MAX_VALUE = 100;
}

不可变性

  • final 关键字使变量成为常量,一旦赋值后不能改变。这确保了常量的值不会被意外修改,从而提高了代码的安全性和可靠性。
public class MyClass {public static final int MAX_VALUE = 100;
}

全局访问

  • static 使得常量可以通过类名直接访问,无需创建类的实例,方便全局使用。
int maxValue = MyClass.MAX_VALUE;

编译期常量

  • static final 常量在编译时就被确定,因此在编译期可以进行优化,比如内联(在使用常量的地方直接替换为常量值)。
public class MyClass {public static final int MAX_VALUE = 100;
}
// 在其他地方使用时
int value = MyClass.MAX_VALUE;  // 编译时会直接替换为 100

使用增强型for循环

有三个循环方式:

static class Counter {int mCount;
}Counter[] mArray = ...public void zero() {int sum = 0;for (int i = 0; i < mArray.length; ++i) {sum += mArray[i].mCount;}
}public void one() {int sum = 0;Counter[] localArray = mArray;int len = localArray.length;for (int i = 0; i < len; ++i) {sum += localArray[i].mCount;}
}public void two() {int sum = 0;for (Counter a : mArray) {sum += a.mCount;}
}

首先,zero()方法是最慢的一种,因为循环的判断条件为 i < mArray.length ,也就是说在每一层循环进行判断时都要重新计算一遍mArray的长度

其次,one()方法相对第一种就快了很多,它直接在循环前就用len保存了长度,不用每层遍历都再计算一遍

two()方法在没有JIT(Just In Time Compiler)的设备上是运行最快的,而在有JIT的设备上运行效率和one()方法不相上下

“JIT” 指的是 “Just-In-Time” 编译,它是一种动态编译技术,用于提高 Java 程序的执行效率。JIT 编译器在 Java 虚拟机(JVM)运行时将字节码编译成本地机器码,从而加快程序的执行速度。

JIT 编译的工作原理

  1. 解释执行
    • 初始阶段,Java 程序的字节码由 JVM 的解释器逐行解释执行。解释执行通常较慢,但不需要编译阶段的开销。
  2. 热点代码检测
    • JVM 会监控代码的执行情况,识别那些频繁执行的代码段,这些代码段被称为“热点代码”。
  3. 编译为机器码
    • 一旦某段代码被识别为热点代码,JIT 编译器会将这段字节码编译成机器码,生成本地可执行代码,从而提高运行速度。
  4. 优化
    • JIT 编译器还会对热点代码进行各种优化,如内联、循环展开、常量折叠等,以进一步提高性能。
  5. 缓存和重用
    • 编译后的机器码会被缓存,以便后续的调用可以直接使用这些优化后的代码,避免重复编译。

使用封装好的API

Java语言当中其实给我们提供了非常丰富的API接口,我们如果能使用系统提供的API就尽量使用,因为系统的API基本上比我们自己写的代码要快得多,它们的很多功能都是通过底层的汇编模式执行的。

避免在内部调用Getters/Setters方法

下面一个例子:

public class Calculate {private int one = 1;private int two = 2;public int getOne() {return one;}public int getTwo() {return two;}public int getSum() {return getOne() + getTwo();}
}

就属于在内部调用getters/setters方法

但其实我们在类的内部可以直接使用类中的封装字段:

public int getSum() {return one + two;
}

布局优化

重用布局文件

<include>的使用

目前几乎所有的软件都会有一个头布局,这个头布局是在所有界面都要使用,但是如果在每个界面都写一次那就太麻烦了,我们可以新建一个布局专门表示头布局,当其他界面要使用的时候直接使用<include>调用就可以了

假设我们随便建了一个头布局

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"android:padding="16dp"android:background="#EEEEEE"><Buttonandroid:layout_width="wrap_content"android:layout_height="wrap_content" /><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center"android:layout_marginStart="8dp"android:text="HaHa"android:textColor="#00dddd"android:textSize="20sp" />
</LinearLayout>

当我们在其他界面要使用的时候就可以直接调用:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"><include layout="@layout/header"/></LinearLayout>

但是如果我们本来的界面中还有别的东西,我们在引入header后所有的东西都有可能被覆盖,出现这个问题是原因是因为header的最外层布局是一个宽高都是match_parent的LinearLayout,我们可以将LinearLayout的layout_height属性修改成wrap_content就可以了,但是这种操作会影响header的界面,如何你只希望让activity_main.xml这一个界面受影响的话,那么可以使用覆写<include>属性的方式

<merge>的使用

<merge> 是 Android 布局文件中的一个特殊标签,用于优化布局结构。它的主要目的是减少布局层级,使布局文件更加高效。<merge> 标签不会创建一个新的视图层级,而是将其子视图直接合并到包含它的布局中。

使用 <merge> 标签的场景:

  1. 优化布局层级:
    • 当你有一个布局文件(如包含多个子视图的布局)需要嵌套在其他布局中时,使用 <merge> 标签可以避免多余的布局层级,从而提高渲染性能。
  2. 简化布局结构:
    • 避免不必要的嵌套布局,减少布局的复杂度和绘制开销。

假设有一个复杂的布局:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="horizontal"><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:text="Hello" /><Buttonandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:text="Click Me" /></LinearLayout><!-- 其他视图 -->
</LinearLayout>

这个布局的嵌套关系如图:

在这里插入图片描述

可以使用merge对布局进行优化:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"><includelayout="@layout/optimized_sub_layout" /><!-- 其他视图 -->
</LinearLayout>

optimized_sub_layout.xml 中使用 <merge> 标签:

<!-- res/layout/optimized_sub_layout.xml -->
<merge xmlns:android="http://schemas.android.com/apk/res/android"><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:text="Hello" /><Buttonandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:text="Click Me" />
</merge>

优化后布局变成了

在这里插入图片描述

参考博客:Android最佳性能实践(三)——高性能编码优化_android 硬编码 节省码率-CSDN博客

Android最佳性能实践(四)——布局优化技巧_android中对布局进行优化-CSDN博客


已经到底啦!!


http://www.ppmy.cn/news/1499813.html

相关文章

四步实现网站HTTPS访问

随着网络安全的重要性日益凸显&#xff0c;HTTPS&#xff08;超文本传输安全协议&#xff09;已成为现代网站的标准配置。HTTPS协议作为HTTP协议的安全版本&#xff0c;通过SSL协议加密数据传输&#xff0c;不仅能保护用户数据的安全&#xff0c;还能提升搜索引擎排名&#xff…

3U/6U CPCI 系统核心模块,可应用于电力、轨道交通等领域

一、3U CPCI核心模块 提供CPCI系列产品&#xff0c;具有&#xff0c;高性能&#xff0c;应用扩展灵活&#xff0c;X86软件兼容&#xff0c;无风扇设计&#xff0c;宽工作温度范围&#xff0c;长嵌入式生命周期等特点&#xff0c;满足不同客户的需求。 产品特点 Intel Pentium …

openCv -- 优势

OpenCV(开源计算机视觉库)是一个广泛使用的计算机视觉和机器学习软件框架。它最初由Intel开发,后来由Itseez公司维护,最终于2015年成为非营利组织OpenCV.org的一部分。OpenCV的目的是实现一个易于使用且高效的计算机视觉框架,支持实时视觉应用。 以下是关于OpenCV的一些关…

聚观早报 | Meta发布Llama 3.1 405B;特斯拉发布二季度财报

聚观早报每日整理最值得关注的行业重点事件&#xff0c;帮助大家及时了解最新行业动态&#xff0c;每日读报&#xff0c;就读聚观365资讯简报。 整理丨Cutie 7月25日消息 Meta发布Llama 3.1 405B 特斯拉发布二季度财报 NVIDIA AI Foundry上线 iPhone 16将改进内部设计 快…

Python入门------pycharm加载虚拟环境

pycharm虚拟环境配置&#xff1a; 在按照前面的办法&#xff0c;配置好虚拟环境后,如果我们需要到虚拟环境开发&#xff0c;就需要给编译器配置虚拟环境 1.打开编译器&#xff0c;点击右下角的interpreter选项 2. 点击ADD Interpreter,添加虚拟环境 3. 因为我们使用的是原始…

安装nfs和rpcbind设置linux服务器共享磁盘

1、安装nfs和rpcbind 1.1 检查服务器是否安装nfs和rpcbind&#xff0c;执行下命令&#xff0c;检查服务器是否安装过。 rpm -qa|grep nfs rpm -qa|grep rpcbind 说明服务器以安装了&#xff0c;如果没有就需要自己安装 2、安装nfs和rpcbind 将rpm安装包&#xff1a; libtirpc-…

JVM 11 的优化指南:如何进行JVM调优,JVM调优参数有哪些

这篇文章将详细介绍如何进行JVM 11调优&#xff0c;包括JVM 11调优参数及其应用。此外&#xff0c;我将提供12个实用的代码示例&#xff0c;每个示例都会结合JVM启动参数和Java代码。 本文已收录于&#xff0c;我的技术网站 java-broke.site&#xff0c;有大厂完整面经&#x…

如何选择适合你的独立站建站工具?

像亚马逊这样的电商平台虽然有完善的流程机制&#xff0c;但是也存在不能留存买家资源、难以进行二次营销等弊端。而跨境卖家布局独立站可以把更多主动权掌握在自己手里。 而对于独立站的搭建&#xff0c;许多刚入行独立站的卖家会选择用现成的框架和模板去组装网站&#xff0c…