推广 热搜: csgo  vue  angelababy  2023  gps  新车  htc  落地  app  p2p 

盘点:35 个 Java 代码优化魔鬼细节

   2023-07-22 网络整理佚名2020
核心提示:可能有些人觉得没用,一些细小的地方有什么好修改的,改与不改对于代码的运行效率有什么影响呢?(2)把原来的4096个字符拷贝到新的的字符数组中去。比如我们用JDBC写一个方法,有10个学生信息字段要插如表中,可以把这10个参数封装在一个实体类中,作为方法的形参。28、字符串变量和字符串常量的时候将字符串常量写在前面33、把一个基本数据类型转为字符串,基本数据类型.

来源|

前言

代码优化是一个非常重要的话题。 有些人可能认为这没什么用。 一些小地方可以修改什么? 对代码的运行效率会有什么影响? 我这样想这个问题,就像海里的鲸鱼,吃一只小虾有用吗? 没什么用,但是吃多了虾,鲸鱼就饱了。

代码优化也是如此。 如果项目的重点是尽快无bug上线,那么此时就可以先大后小,对代码的细节进行微调; 但如果你有足够的时间来开发和维护代码,这个时候你就必须考虑每一个可以优化的细节。 小的优化点一点一滴的积累,一定会提高代码的运行效率。

代码优化的目标是:

1、尽量指定类和方法的final修饰符

带有final修饰符的类是不可派生的。 在Java核心API中,有很多应用final的例子,例如java.lang。 整个班级都是最终的。 为类指定final修饰符可以防止该类被继承,为方法指定final修饰符可以防止该方法被覆盖。 如果一个类被指定为final,则该类的所有方法都是final的。 Java 编译器将寻找机会内联所有最终方法。 内联对于提高Java运行效率有着重要的作用。 有关详细信息,请参阅 Java 运行时优化。 这可以将性能平均提高 50%。

2. 尽可能重复使用对象

特别是,当发生字符串串联时,应该使用对象而不是 / 。 由于Java虚拟机不仅需要时间来生成对象,而且将来可能还需要花费时间对这些对象进行垃圾收集和处理,因此,生成过多的对象会对程序的性能产生很大的影响。

3.尽可能使用局部变量

调用方法时传递的参数以及调用过程中创建的临时变量存储在堆栈中的速度较快,而其他变量,例如静态变量和实例变量则创建在堆中,速度较慢。 另外,栈中创建的变量会随着方法结束而消失,不需要额外的垃圾回收。

4.及时关闭流

在Java编程中,进行数据库连接和I/O流操作时要小心。 使用完毕后及时关闭,释放资源。 因为这些大对象的操作会造成很大的系统开销,稍有不慎就会导致严重的后果。 如果条件允许,即JDK7以上,强烈建议使用try-with-。

5. 尽量减少变量的重复计算

澄清一个概念,调用一个方法,即使方法里只有一句话,也是消耗的,包括创建栈帧、调用方法时保护场景、恢复方法调用时场景。 例如以下操作:

建议将其替换为:

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

6、尽量采用懒加载策略,即只在需要的时候创建*

例如:

建议将其替换为:

7. 谨慎使用异常

异常不利于性能。 要抛出异常,必须首先创建一个新对象。 接口的构造函数调用名为的本地同步方法。 该方法检查堆栈并收集调用跟踪信息。 每当抛出异常时,Java 虚拟机就必须调整调用堆栈,因为在处理过程中会创建一个新对象。 异常应该只用于错误处理,而不应该用于控制程序流程。

8.循环中不要使用try...catch...,应该放在最外层

除非你必须这样做。 如果你无缘无故地写出这样的东西,只要你的领导比较有经验,有强迫症,他很可能会骂你写出这样的垃圾代码。

9. 如果要添加的内容的长度可以估计,则为以数组形式实现的底层集合和工具类指定初始长度

如、、、、、等,举个例子:

(1) // 默认分配16个字符

(2) (int size) // 默认情况下,分配size个字符的空间

(3) (str) // 默认分配16个字符 + str. 字符空间

它的初始化能力可以通过类来设置(这里指的不仅仅是上面),这样可以显着提高性能。 例如,表示当前可以保留的字符数。 因为当达到最大容量时,它会将自己的容量增加到当前容量的2倍加2,每当达到最大容量时,它就必须创建一个新的字符数组,然后将旧的字符数组内容复制到新的字符数组中——这是一个非常消耗性能的操作。 试想一下,如果在不指定长度的情况下,可以估计字符数组中会存储大约5000个字符,最接近的2到5000的幂是4096,每次扩展加2也没关系,那么:

(1)在4096的基础上,申请8194个字符数组,相当于一次性申请12290个字符数组。 如果一开始就可以指定5000个字符数组,那么将节省一倍以上的空间;

(2) 将原来的4096个字符复制到新的字符数组中。

这样就浪费了内存空间,降低了代码运行效率。 因此,为数组实现的底层集合和工具类设置合理的初始化容量是没有错的,会带来立竿见影的效果。 不过要注意,像这种数组+链表实现的集合,不要把初始大小设置成和你预估的大小一样,因为一张表上只连接一个对象的可能性几乎为零。 建议将初始大小设置为2的N次方。如果可以估计有2000个元素,可以设置为new(128)或new(256)。

10、复制大量数据时,使用.命令

11.乘法和除法使用移位运算

例如:

使用移位操作可以大大提高性能,因为在计算机底层,位的操作是最方便、最快的,所以建议修改为:

移位操作虽然很快,但是可能会导致代码难以理解,所以最好添加相应的注释。

12.不要在循环中不断创建对象引用

例如:

这种方法将导致内存中存在 count 个对象引用。 如果计数太大,就会消耗内存。 建议改为:

这种情况下,内存中只有一份对象引用,而每次new时,对象引用都指向不同的一个,但内存中却只有一份,这样就大大节省了内存空间。

13、基于效率和类型检查的考虑,尽可能使用数组,只有在无法确定数组大小的情况下才使用数组。

14.尽量使用,,除非线程安全需要,否则不建议使用,,,后三者由于使用同步机制造成性能开销

15.不要将数组声明为final

因为这是没有意义的,它只是将引用定义为final,而数组的内容仍然可以随意改变。 将数组声明为安全漏洞更像是一个安全漏洞,这意味着该数组可以被外部类更改。

16.在适当的场合尝试使用单例

使用单例可以减轻加载负担,缩短加载时间,提高加载效率,但并不是所有的地方都适合单例。 简单来说,单例主要适用于以下三个方面:

(1)控制资源的使用,通过线程同步控制资源的并发访问

(2)控制实例的生成,达到节省资源的目的

(3) 控制数据的共享,在多个不相关的进程或线程之间实现通信,无需建立直接关系

17.尽量避免随意使用静态变量

要知道,当一个对象被定义为 的变量引用时,那么 gc 通常不会回收这个对象占用的堆内存,如:

此时,静态变量b的生命周期与A类相同。如果A类没有被卸载,则引用B指向的B对象将一直保留在内存中,直到程序终止。

18.及时清理不再需要的东西

为了清除不再活动的会话,许多应用程序服务器都有默认的会话超时,通常为 30 分钟。 当应用服务器需要保存更多的会话时,如果内存不足,操作系统会将部分数据转移到磁盘上,应用服务器也可能会根据MRU(最近使用)算法将一些不活动的会话转储到磁盘上,甚至可能会抛出内存不足的异常。 如果要将会话转储到磁盘,则必须首先对其进行序列化,而在大型集群中序列化对象的成本可能会很高。 因此,当不再需要会话时,应该及时调用方法来清除会话。

19、实现接口的集合比如应该使用最常见的for循环而不是循环来遍历

这是JDK向用户推荐的。 JDK API对该接口的解释是:该接口的实现用于表明其支持快速随机访问。 该接口的主要目的是允许通用算法改变其行为,以便在应用于随机或连续访问列表时能够提供良好的性能。 实践经验表明,如果随机访问实现接口的类实例,使用普通for循环的效率会比使用循环更高; 反之,如果按顺序访问,使用效率会更高。 可以使用类似下面的代码来进行判断:

循环的底层实现原理是迭代器,参见Java语法糖1:变长参数和循环原理。 所以后半句“相反,如果是顺序访问的话,使用效率会更高”,意思就是那些顺序访问的类实例,使用循环来遍历。

20.使用同步代码块而不是同步方法

这一点在《多线程模块中的Lock方法块》一文中已经说得很清楚了。 除非能确认整个方法需要同步,否则尽量使用同步代码块,避免同步不需要同步的代码,影响代码执行效率。

21.将常量声明为final并以大写命名

这样就可以在编译时将这些内容放入常量池中,避免运行时计算生成常量值。 另外,用大写命名常量也可以很容易区分常量和变量。

22.不要创建一些未使用的对象,不要导入一些未使用的类

这是没有意义的,如果代码中出现“The value of the local i is ”、“The java.util is ”,那么请删除这些无用的内容

23、程序运行时避免使用反射

有关的信息,请参阅反射。 反射是Java为用户提供的一个非常强大的功能,而强大的功能往往意味着低效率。 不建议使用反射机制,特别是在程序运行过程中频繁使用反射机制。 如果确实有必要,建议的做法是通过反射实例化一个对象,并在项目启动时将其放入内存中。

24、使用数据库连接池和线程池

两个池都是用来复用对象的,前者可以避免频繁打开和关闭连接,后者可以避免频繁创建和销毁线程。

25.使用缓冲输入和输出流进行IO操作

缓冲输入输出流,即,,,,这样可以大大提高IO效率。

26、顺序插入和随机访问较多的场景使用这个,元素删除和中间插入较多的场景使用这个,就知道sum的原理了。

27.不要让方法有太多形参

方法是外部提供的方法。 如果给这些方法太多的形式参数,则有两个主要缺点:

1、违背了面向对象编程的思想。 Java强调一切皆对象。 太多的形式参数不符合面向对象编程的思想。

2、参数过多必然导致方法调用出错概率增加

至于“太多”指的是多少个,可能是3个,也可能是4个。比如我们用JDBC写一个方法,有10个学生信息字段要插入到表中,这10个参数就可以封装在一个实体类中,作为该方法的形参。

28、写字符串变量和字符串常量时,把字符串常量写在前面

这是一个比较常见的trick,如果有下面的代码:

建议修改为:

这主要是为了避免空指针异常。

29、请注意,java中if(i==1)和if(1==i)没有区别,但是从阅读习惯上来说,建议使用前者

人们通常会问,“if (i == 1)”和“if (1== i)”有什么区别吗?它以C/C++开头。

在C/C++中,“if(i==1)”判断条件成立,基于0和非零,0表示假,非零表示真,如果有这样一段代码:

C/C++判断“i==1”不为真,所以用0表示,为假。 但如果:

万一程序员不小心把“if(i==1)”写成了“if(i=1)”,就会出现问题。 在if内给ia赋值1,if判断里面的内容不为0,返回值为true,但显然i是2,比较的值为1,应该返回false。 这种情况在C/C++开发中很有可能发生,并且会导致一些难以理解的错误。 因此,为了避免开发者在if语句中进行错误的赋值操作,建议将if语句写成:

这样,即使开发人员不小心写成了“1 = i”,C/C++编译器也能第一时间检查出来,因为我们可以将i赋给1给变量,但我们不能将1赋给i给常量。

然而在Java中,C/C++的“if(i=1)”语法是不可能的,因为一旦写出这个语法,Java就会编译并报错“Type: from int to”。 不过,虽然Java的“if(i==1)”和“if(1==i)”在语义上没有区别,但从阅读习惯来看,还是推荐使用前者更好。

30. 不要在数组上使用方法

看看使用数组打印的内容:

结果发现:

目的是打印出数组的内容,但可能会导致空指针异常,因为数组引用为空。 不过,虽然对于数组来说没有意义,但是对于集合来说却可以打印出集合的内容,因为集合的父类重写了该方法。

31. 不要向下转型为超出范围的原始数据类型

这永远不会得到期望的结果:

我们可能期望得到其中一些位,但结果是:

解释。 Java中的Long是8字节64位,所以234在计算机中的表示应该是:

0 0 0 0 0 0010

一个int类型数据是4个字节32位,上面这串二进制数据取低位的前32位为:

0 1 1111 0010

这串二进制表示为十进制,所以就是我们上面控制台输出的内容。 从这个例子可以得出两个结论:

1、默认的数据类型是int,long l = 234L,这个数字超出了int的范围,所以末尾有一个L,表示是long类型的数字。 顺便说一句,浮点数的默认类型是,所以定义float时应该写成“”float f = 3.5f”

2. 接下来,写下句子“int ii = l + i;” 并且会报错,因为long + int是long,不能赋值给int

32、公共集合类中未使用的数据必须及时丢弃

如果一个集合类是公共的(即不是方法中的属性),那么这个集合中的元素将不会自动释放,因为总是有对它们的引用。 因此,如果公共集合中的某些数据没有被使用并且没有被移除,就会导致公共集合不断增长,导致系统存在内存泄漏的隐患。

33.将基本数据类型转换为字符串,基本数据类型是最快的方式,其次是data + "" 最慢

可通过三种方法将基本数据类型转换为通用数据类型。 我有一个类型数据 i,我可以通过三种方式使用 i., .(i), i+"" 。 这三种方式的效率如何? 我们来看一个测试:

运行结果为:

所以以后遇到基本数据类型转换为 的时候,优先使用该方法。 至于为什么,很简单:

1、.底层调用.,但是调用前会做空判断

2.方法不说,直接调用即可

3、i+""底层使用实现,先使用方法进行拼接,然后使用方法获取字符串

比较三者,很明显2最快,1第二,3最慢。

34.用最有效的方式遍历地图

遍历地图的方法有很多种。 一般来说,我们需要的是遍历Map中的Key和Value。 推荐且最有效的方法是:

如果只是想遍历这个Map的键值,那么使用“Set=hm.;”会更合适

35.建议单独操作资源的关闭

意思是,例如我有这样一段代码:

建议修改为:

虽然麻烦一点,但是可以避免资源泄漏。 我想,如果没有修改代码的话,如果XXX.close抛出异常,那么就会进入cath块,YYY.close不会被执行,YYY资源也不会被回收,一直被占用。 如果此类代码太多,可能会导致资源句柄泄漏。 改成上面的写法后,保证XXX和YYY无论如何都会被关闭。 如果是JDK7以上,强烈建议使用try-with-。


ntent="t">

inktype="1">nback="static" style="inset: auto;">

ntent="t">本月21日~23日,由 IT168 旗下 ITPUB 企业社区平台主办的第十一届中国数据库技术大会(DTCC2020),将在北京隆重召开。大会以“架构革新 高效可控”为主题,设置2大主会场,20+技术专场,将邀请超百位行业专家,重点围绕数据架构、AI与大数据、传统企业数据库实践和国产开源数据库等内容展开分享和探讨,为广大数据领域从业人士提供一场年度盛会和交流平台。

ntent="t">

ntent="t">为了帮助更多企业落地数据项目实施方案,今年将继续开设多门深度培训课程,内容涵盖数据中台、去IOE实践、区块链技术、内核开发实践等。3天传统技术演讲+1天深度主题,将汇聚各行业精英、技术领袖、行业专家和数据英雄,带来超过100场主题演讲和超5场培训课程的头脑风暴,诚邀您的加入。


inktype="2" style="color: rgb(0, 122, 170);font-size: 12px;font-family: Optima-Regular, PingFangTC-light;">放弃腾讯75W年薪,回老家当公务员,提离职被领导教育,网友:leader嫉妒了
inktype="2" style="color: rgb(0, 122, 170);font-size: 12px;font-family: Optima-Regular, PingFangTC-light;">王垠:怎样尊重一个程序员?
inktype="2" style="color: rgb(0, 122, 170);font-size: 12px;font-family: Optima-Regular, PingFangTC-light;">年薪30万+的程序员,都是这样谈薪资的...
inktype="2" style="color: rgb(0, 122, 170);font-size: 12px;font-family: Optima-Regular, PingFangTC-light;">2020年11月DB-Engines排行:Oracle归零年内涨幅 PostgreSQL增长第一独秀
inktype="2" style="color: rgb(0, 122, 170);font-size: 12px;font-family: Optima-Regular, PingFangTC-light;">中国程序员 VS 印度程序员,太有味了...
inktype="2" style="color: rgb(0, 122, 170);font-size: 12px;font-family: Optima-Regular, PingFangTC-light;">快手回应厕所装坑位计时器,这届打工人:再也不能愉快地带薪拉屎了?
inktype="2" style="color: rgb(0, 122, 170);font-size: 12px;font-family: Optima-Regular, PingFangTC-light;">伟大&耀眼,C语言发展史的点点滴滴
inktype="2" style="color: rgb(0, 122, 170);font-size: 12px;font-family: Optima-Regular, PingFangTC-light;">中国程序员VS美国程序员,这也太形象了吧...
inktype="2" style="color: rgb(0, 122, 170);font-size: 12px;font-family: Optima-Regular, PingFangTC-light;">研究主攻数据库和磁盘故障优化,曾经复读才考上三本,他如今让华为开出201万年薪
inktype="2" style="color: rgb(0, 122, 170);">DBA林工:OracleDG 环境主备业务数据不同步备库报 ORA-600 错误怎么整?
inktype="2" style="color: rgb(0, 122, 170);font-size: 12px;font-family: Optima-Regular, PingFangTC-light;">有个程序员老公有多爽???
inktype="2" style="color: rgb(0, 122, 170);font-size: 12px;font-family: Optima-Regular, PingFangTC-light;">为什么不建议把数据库部署在docker容器内?
inktype="2" style="color: rgb(0, 122, 170);letter-spacing: 0.544px;font-size: 12px;font-family: Optima-Regular, PingFangTC-light;">A里正在拆中台,你还在建中台吗?
inktype="2" style="color: rgb(0, 122, 170);font-size: 12px;font-family: Optima-Regular, PingFangTC-light;">腾讯技术专家:解密小程序云开发数据库 | 干货
inktype="2" style="color: rgb(0, 122, 170);font-size: 12px;font-family: Optima-Regular, PingFangTC-light;">微服务架构框架?这里为你汇总了15种
inktype="2" style="color: rgb(0, 122, 170);font-size: 12px;font-family: Optima-Regular, PingFangTC-light;">阿里P8税后收入170万?P8、P9 及以上到底是什么水平?
inktype="2" style="color: rgb(0, 122, 170);font-size: 12px;font-family: Optima-Regular, PingFangTC-light;">Matlab 被禁只是冰山一角!一个海外资深程序员聊被卡脖子……

SACC2020中国系统架构师大会

DTCC中国数据库技术大会2010-2019
SACC2019中国系统架构师大会
PostgreSQL 2019中国技术大会
点击上方文字可以直接进入小程序浏览,
下载请在后台分别回复关键词
 DTCC、SACC、PG19
即可直接收到完整版 PPT 下载链接~


「在看」吗?

 
反对 0举报 0 收藏 0 打赏 0评论 0
 
更多>同类资讯
推荐图文
推荐资讯
点击排行
网站首页  |  关于我们  |  联系方式  |  使用协议  |  版权隐私  |  网站地图  |  排名推广  |  广告服务  |  积分换礼  |  网站留言  |  RSS订阅  |  违规举报
Powered By DESTOON