java也做了很久,自己也积累了一些代码优化的心得。 好的代码是体现程序员水平的最直观的表达。 让我们来看看代码方面常见的优化点
(本文在写作过程中也参考了其他文章,在此不再一一赘述。 内容也很浅显,忘记了大神吹得很轻,如果有错误的地方,请在评论中指出来。 一一修正。
1 .减少变量的重复计算----" for循环优化
for(intI=0; i args.length; 将I )改为。
for(intI=0,index=args.length; i index; I ) )原理: args.length在每次I时重新计算(调用),优化后只计算一次)
当然这也是对args大的时候,args不大的时候,其实效率也是一样的,但我们养成好习惯总是好的。 另外,由于可以直接修改for循环的模板来实现,所以很方便
修改eclipse模板: preferences-Java-editor-templates找到for并修改为上面的内容
——————————————————————————————————————————
有人评论说PS:是错误的,这里放上demo。 希望评论者能慎重起来
此优化的原理是通过1,000次size (方法调用和一次size )方法调用来提高性能,但这种性能很少
但是,他也说,数据量大的情况下有明显的效果,数据小的情况下效果不大
也许是我写了“计算”这个词,误会了别人,其实是调用,只是写惯了
_
在公司里写了demo。 你自己看吧。 出来的数据在下面。 前面还很正常。 后面的JIT介入的话,基本上是0
当然,在实际的代码中也没有人写1000W的List,但是不能否认这个优化是错误的。 只是在数据量少的时候效果不明显
——————————————————————————————————————————
2 .下层使用可变排列的数据结构尽量指定长度
例如,最常用的ArrayList、HashMap
liststringlist=newArraylist(10; MapString,objectmap=newHashmap(10; 原理:可变数组具有扩展策略,当数据量超过加载因子时,会执行扩展操作
如果指定了长度,则只有在超出指定长度时才会执行扩展操作,因此应该尽可能地使用它来估计大小,并尽可能地指定大小
3.String类尽量使用StringBuffer、StringBuilder
这与jvm的内存分配有关,举个例子
String str=“abc”; string str2=str“CCD”JVM在堆内存中打开三个空间。 1是“abc”,2是“ccd”,3是“abcccd”,最终str2指向3。 1和2未被参考,因此在GC回收机制内回收。 GC的开销相当大,请尽量避免
那么,使用StringBuffer怎么样
StringBuffer str=“abc”; str.append(「CCD”; jvm只在堆空间中打开一个空间“abc”,在执行append时只在“abc”的空间中制作“ccd”
因此,可以避免GC的回收,也可以避免内存的浪费
同样是为了获得“abcccd”,但第二种方法明显更有效率
那么,如何判断使用的是StringBuffer还是StringBuilder呢?
考虑到有线进程的安全性,如果使用StringBuffer,而不使用StringBuilder,线程安全性也会增加很多开销
equals ) )方法时,常数尽量写在前面
例如:
Brand brand=new Brand (; brand.setimgurl(dddddddd ); //brand.setname(hfanss ); String ss='HFanss '; if(brand.getname ).equals(ss ) ) {System.err.println ('相同'); }else{ System.err.println ('不相同); }抛出空指针异常。 请按以下方式修改。
if(ss.equals(brand.getname ) ) ) ) ) ) ) ) ) ) if ) ) ) ) ) if ) ) ) ) ) ) if ) ) ) ) ) ) getname
原理:如果equals的源代码解释比较对象(常量ss )为空,则抛出空指针异常。
另外,如果比较对象(brand.getName () )为空,则直接以false结束
5 .尽量采用懒惰加载的策略,就是在必要的时候制定
例如:
String str='HFanss '; if(2).equals(status ) ) list.add (str ); }应该是:
国际机场
("2".equals(status)) { String str = "HFanss"; list.add(str); }原理:这个应该很容易看懂的,当if不成立时,创建的字符串就没用了,面临GC回收,应该有效避免,写在if内部
6. 在数值运算时,遇到偶数乘、除偶数倍时,尽量使用位移运算
如:
int a = 2;int b = 16;System.err.println(a<<5);//等同于 2*2*2*2*2*2 即2*32System.err.println(b>>2);//等同于 16/2/2 即16/4原理:即使使用 2*32、16/4的方式,最终在底层的算法还是位移,因为位移是基于2进制的算法,任何运算都会转换成二进制再运算,那我们直接使用二进制就会提升一部分效率
7. 对象引用的优化
如:
List<Object> list = new ArrayList<>();for (int i = 0; i < 1000; i++){ Object obj = new Object(); list.add(obj);}应该为:
List<Object> list = new ArrayList<>();Object obj = null;for (int i = 0; i < 1000; i++){ obj = new Object(); list.add(obj);}原理:我们的目的只是list.add(obj)这一步,
前者obj引用会在栈空间中有1000个,但是最终只会用到1个,
后者obj引用在栈空间只有1个,提升效果不言而喻!
8. 慎重使用static静态
使用静态后,编译时会直接创建,而且直到程序结束,一般只会用在常量,公共方法上,因为需要保证随时随地使用,基于这一需求,它不太使用于对象的创建上,会浪费内存
9. 常量的优化
相信这个大家应该都很熟悉,常量名大写 用以和变量区分,而且加上static final修饰,保证使用的速度和不被外界力量所改变
10. 将变量转换成字符串时尽量使用to.string()方法
一般有3种方法
Integer s = 5;s.toString();String.valueOf(s);//源码显示调用了Integer.toString()方法,而且会在调用前做空判断s+“”;//源码显示使用StringBuilder实现,先用append方法拼接,再用toString()方法对比而言,直接调用最底层的toString()方法无疑是效率最高的接下来是一些体系上的优化,分为 结构优化,日志优化,可读性优化,异常优化
结构优化:
A. action层尽量不要做参数的校验和逻辑书写,它只负责请求的转发和响应,入参和出参
B. Service层逻辑要清晰,尽量不要有if,for的出现,全部封装到公共方法去调用
C. DAO层只提供持久层相关操作,如封装参数进map供持久层使用,尽量不要有逻辑hcdzfj,所有的逻辑应都在service里完成
日志优化:
A. 方法开始后、结束前书写日志
B. 抓取异常时书写日志
C. 特殊情况时书写。如需要提前return时
可读性优化:
A. 类、方法必须要有注释
B. 在一些比较大的逻辑前加上注释
C. 一个完美的service层,应逻辑清晰,一行代码代表一个逻辑,通篇下来可读性非常强
异常优化:
A. 异常应只用来进行错误处理,而不是逻辑处理(异常也是高开销的操作)
B. 善用多种异常,但是在service层应只有一个 try cath来抓取多个异常,并分别处理
C. 异常理应在service层全部处理完,不能再继续往上抛(理论上可以接续抛,但service本来就是处理逻辑的,尽量在本层处理完)
以上是代码优化方面的一些常见点,当然这并不是全部,一个完美的代码是有很多优化点的,而且代码优化方面也不止这些,本人只是基于自己的经验给新来的同志一些借鉴之处。
除了代码优化,还有一些容器优化,项目优化,网络优化,缓存优化等等,编程是一个枯燥的过程,望共勉之!
最后给大家安利一个好用的插件--》阿里巴巴代码规范检测插件
红框内的就是执行检测后提示的信息,会提示不符合阿里巴巴规范的代码
安装使用教程 : 点我