【Java】java开发过程中一些优化的小细节

news/2024/9/22 14:24:33/

优化的小细节

  • List优化
  • 尽量减少对变量的重复计算:
  • 用移位代替乘除操作:
  • 循环内不要不断创建对象引用:
  • 常量和变量使用equals比较,常量建议写在前边
  • 其他优化

List优化

对于不同类型的list,遍历时选择合适的迭代方式(最常用的ArrayList和LinkedList):
1)ArrayList实现了RandomAccess接口,使用普通for循环遍历性能比较好(实现RandomAccess接口表明其支持快速随机访问,jvm决定)
2)LinkedList没有实现RandomAccess接口,使用超级for循环(foreach)或者iterator迭代性能比较好

尽量减少对变量的重复计算:

明确一个概念,对方法的调用,即使方法中只有一句语句,也是有消耗的,包括创建栈帧、调用方法时保护现场、调用方法完毕时回复现场等。所以如下操作

For(int i = 0;i < list.size();i ++) {…}

建议替换为

For(int i = 0,size = list.size();i < size;i ++) {

}

这样,当list.size()很大的时候,就减少了很多的消耗

用移位代替乘除操作:

计算机层面运行的是机器可以识别的二进制码,所以性能层面的话,移位高于乘法,乘法性能高于除法(可以参考jdk源码)。例如Integer.java中有一段代码

r = i - ((q << 6) + (q << 5) + (q << 2));
等价于r = i - (q * 64 + q * 32 + q * 4)=i - (q * 100);
r = i - ((q << 3) + (q << 1));
等价于 r = i - (q * 8 + q * 2) = i - (q * 10);
*其中还有一段q = (i * 52429) >> (16 + 3)
明显是使用移位和乘法替代除法操作,因为2 <<(16 + 3) = 2 << 19 = 524288,所以(i * 52429)>>>(16+3) = i * 52429 / 524288 ≈ i * 0.1 = i / 10;

循环内不要不断创建对象引用:

例如

for(int i = 0; i < count; i ++) {
Object obj = new Object();
}

这种方式会导致内存中有count份Object对象引用存在,如果count很大的话,就很耗费内存了;
建议改为:

Object = null;
for(int i = 0;i < count;i ++){
obj = new Object();
}

这样内存中只存在一份Object对象引用,每次new的时候只想不同的Object

常量和变量使用equals比较,常量建议写在前边

例如:

a.String str = “123”;
if(str.equals(“123”)){…}

建议改为

if(“123”.equals(str)){…}

这样可以避免空指针(str = null时不会报NullPointerException)

@JVM 参数调优:
-Xms表示 JVM 初始化堆的大小,-Xmx表示 JVM 堆的最大值。这两个值的大小一般根据需要进行设 置。当应用程序需要的内存超出堆的最大值时虚拟机就会提示内存溢出,并且导致应用服务崩溃。因此一般建议堆的最大值设置为可用内存的最大值的 80%。
在 catalina.bat中,设置 JAVA_0PTS=‘-Xms256m- Xmx512m’,表示初始化内存为 256MB,
可以使用的最大内存为 512MB。

其他优化

将基本类型转为字符串,(类型).toString()最快,String.valueOf()次之, + “”最慢
使用有效率的方式遍历Map
便利map的方式很多,通常场景下需要遍历的是Map中的key和value,那么推荐使用的、效率最高的方式是:


Map<String,Object> map = new HashMap<>();
Map.put(111,222);Set<Map.Entry<String,Object>> entrySet = map.entrySet();Iterator<Map.Entry<String,Object>> iterator = entrySet.iterator();while (iterator.hasNext()) {Map.Entry<String,Object> entry = 					(Map.Entry<String,Object>)iterator.next();}

尽可能重用对象
特别是String对象的使用,出现字符串链接时应该使用StringBuilder/StringBuffer代替(如果是方法内局部变量拼接,建议使用StringBuilder,后者同步,性能差一些)。由于jvm不仅要花时间生成对象,以后可能还要花时间对这些对象进行垃圾回收和处理,因此,生成过多的对象将会给程序的性能带来很大的影响

如果能够预估到待添加内容的长度,为底层以数组方式实现的集合、工具类指定初始长度
比如ArrayList,LinkedList,StringBuilder,StringBuffer,HashMap,HashSet等
如果动态频繁添加数据,底层数组会发生频繁扩容,并且底层的扩容是新建数组,使用System.copy实现,替代旧数组,导致频繁的复制.

当复制大量数据时,使用System.arrayCopy()命令


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

相关文章

小程序_图片转canvas,上传和rgb888转rgb565发送到设备

序:小程序需要将图片上传到蓝牙设备,那么图片要转为二进制数据,转为二进制的图片数据不能过大,就要裁剪图片,因为要尽量减少图片的二进制数据,要将图片的rgb888转为rgb565,也就是24位缩小为16位数据;例如:100像素*100像素的图片,就有1万个点,一个点包含rgba四个数,…

不可忽视的 C 语言陷阱!

已剪辑自: https://mp.weixin.qq.com/s/bdGuOjz1Cg3YXHwlVh5ZlA 语言是编程的基石&#xff0c;C语言诡异且有种种陷阱和缺陷&#xff0c;需要程序员多年历练才能达到较为完善的地步。 虽然有众多书籍、杂志、专题讨论过C语言的陷阱和缺陷&#xff0c;但这并不影响本文再次讨论…

Centos下自定义安装Redis远程字典服务

记录一下在centos7.x下面自定义安装redis的方式 首先确认系统是否已安装redis&#xff0c;最快捷的方式是查看redis的版本信息 如果之前用yum安装的&#xff0c;用下面这种方式可能看到版本信息&#xff0c;如果是自定义安装&#xff0c;指令无效 redis-server --version (建…

【JavaSE】文件读写

目录 一、文件 1、文件的概念 1.广义 2.狭义 二、路径 1、绝对路径 2、相对路径 1.进入下一级./ 2.回退上一级../ 三、Java里的文件基本操作----File类 1、说明 2、File类的基本操作 1.基本方法 ​2.创建与删除文件 3.创建目录 4.文件的重命名 四、文件的读写操…

Qt + OpenCV 部署yolov5(多线程)

文章目录 一、新建项目 UI设计二、代码部分mainwindow 类detector类yolov5类三、效果演示项目基于 Qt + OpenCV 部署yolov5 添加了检测线程(主线程负责主窗口UI显示)避免拖动窗口时卡顿 #mermaid-svg-57ytMm4sbTpUi2CM {font-family:"trebuchet ms",verdana,arial…

基于Java毕业设计学习和分享做菜web系统源码+系统+mysql+lw文档+部署软件

基于Java毕业设计学习和分享做菜web系统源码系统mysqllw文档部署软件 基于Java毕业设计学习和分享做菜web系统源码系统mysqllw文档部署软件本源码技术栈&#xff1a; 项目架构&#xff1a;B/S架构 开发语言&#xff1a;Java语言 开发软件&#xff1a;idea eclipse 前端技术…

vue前后端分离项目打包成app,部署成移动端

将vue项目打包成app,在手机上运行。 1. vue打包 npm run build 先将vue的前端项目打包成dist文件夹 2. 安装hbuilderX Hbuilder官网地址 3. hbuilderX 1&#xff09;新建项目 我是vue的&#xff0c;所以直接选择的h5app&#xff0c;然后起个名字&#xff0c;选择路径。 2…

Java+SSM在线商城系统电商购物系统(含源码+论文+答辩PPT等)

项目功能简介: 该项目采用的技术实现如下 后台框架&#xff1a;Spring、SpringMVC、MyBatis UI界面&#xff1a;BootStrap、jQuery 、JSP 数据库&#xff1a;MySQL 系统分为前台订票和后台管理&#xff1a; 1.前台商城 商品分类展示、商品详情、商品推荐、购物车、下单、支付 客…