博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Java代码性能优化常用方法
阅读量:2004 次
发布时间:2019-04-28

本文共 4743 字,大约阅读时间需要 15 分钟。

目录

 


1. 尽量使用final修饰符

带有final修饰符的类是不可派生的。在JAVA核心API中,有许多应用final的例子,例如java、lang、String,为String类指定final防止了使用者覆盖length()方法。另外,如果一个类是final的,则该类所有方法都是final的。java编译器会寻找机会内联(inline)所有的final方法(这和具体的编译器实现有关),此举能够使性能平均提高50%。

如:让访问实例内变量的getter/setter方法变成”final:

简单的getter/setter方法应该被置成final,这会告诉编译器,这个方法不会被重载,所以,可以变成”inlined”,例子

public class Student {    private String name;    private Integer age;//普通使用    final public String getName() {        return name;    }    final public Integer getAge() {        return age;    }//优化使用    public String getName() {        return name;    }    public Integer getAge() {        return age;    }}

2.. 尽量减少对变量的重复计算

如:

for(int i=0;i
  • 上面的每次循环都要交计算list.size(),下面的将list.size()首先计算出来放入变量len,避免了多次重复计算

应该改为:

for(int i=0,len=list.size();i

并且在循环中应该避免使用复杂的表达式,在循环中,循环条件会被反复计算,如果不使用复杂表达式,而使循环条件值不变的话,程序将会运行的更快。

3.. 尽量避免不必要的创建

如:

A a = new A();if(i==1){list.add(a);}//应该改为下面的代码,因为上面的是先创建对象,然后再判断是否添加,如果不符合if条件,那么对象也会被创建影响性能if(i==1){A a = new A();list.add(a);}

4. 尽量使用移位来代替’a/b’和’a*b’的操作

“/”和‘*’是一个代价很高的操作,使用移位的操作将会更快和更有效

如:

int num = a / 4;int num = a / 8;//应该改为int num = a >> 2;int num = a >> 3;int num = a * 4;int num = a * 8;//应该改为int num = a << 2;int num = a << 3;

 

 

5. 尽量确定StringBuffer的容量

StringBuffer 的构造器会创建一个默认大小(通常是16)的字符数组。在使用中,如果超出这个大小,就会重新分配内存,创建一个更大的数组,并将原先的数组复制过来,再丢弃旧的数组。在大多数情况下,你可以在创建 StringBuffer的时候指定合适的大小,这样就避免了在容量不够的时候自动增长,以提高性能。无论何时,只要StringBuffer到达它的最大容量,它就不得不创建一个新的对象数组,然后复制旧的对象数组,这会浪费很多时间。所以给StringBuffer设置一个合理的初始化容量值,是很有必要的!

如:

StringBuffer buffer = new StringBuffer(1000);

 

StringBuffer初始化时,其容量大小(Capacity)为16;其后容量不够时按照9*(2的n次方)来增长。

当对字符串进行修改的时候,需要使用 StringBuffer 和 StringBuilder 类。

和 String 类不同的是,StringBuffer 和 StringBuilder 类的对象能够被多次的修改,并且不产生新的未使用对象。

StringBuilder 类在 Java 5 中被提出,它和 StringBuffer 之间的最大不同在于 StringBuilder 的方法不是线程安全的(不能同步访问)。

由于 StringBuilder 相较于 StringBuffer 有速度优势,所以多数情况下建议使用 StringBuilder 类。然而在应用程序要求线程安全的情况下,则必须使用 StringBuffer 类。 相同情况下,使用StringBuilder比使用StringBuffer仅能获得10%~15%的性能提升,但却要冒多线程不安全的风险。综合考虑还是建议使用StringBuffer。

public static void main(String[] args) {            StringBuffer buffer= new StringBuffer(100);        buffer.append(66);        buffer.append("我是学生");        System.out.println(buffer);        StringBuilder builder=new StringBuilder(100);        /**         * public StringBuffer append(String s)         * 将指定的字符串追加到此字符序列。         */        builder.append(12);        builder.append("我是学生1");        builder.append("我是学生2");        builder.append("我是学生3");        System.out.println(builder);        /**         * public delete(int start, int end),         * start:开始的字符串的位置,从0开始,end:结束的字符串的位置         */        builder.delete(0,3);        /**         * public insert(int offset, object i)         * 将参数i的字符串表示形式插入此序列中。         * offset:从什么位置开始插入         */        int i =12;        builder.insert(0,i);        System.out.println(builder);        /**         * int length()         *  返回长度(字符数),中文和英文都算一个字符         */        System.out.println(builder.length());        /**         *String toString()         *返回此序列中数据的字符串表示形式。         */        builder.toString().split("");            }

6. 尽量避免使用二维数组

二维数据占用的内存空间比一维数组多得多,大概10倍以上。

7. 尽量避免使用split

除非是必须的,否则应该避免使用split,split由于支持正则表达式,所以效率比较低,如果是频繁的几十,几百万的调用将会耗费大量资源,如果确实需要频繁的调用split,可以考虑使用apache的StringUtils.split(string,char),频繁split的可以缓存结果。

8. ArrayList (线性表)& LinkedList(链表)

一个是线性表,一个是链表,一句话,随机查询尽量使用ArrayList,ArrayList优于LinkedList,LinkedList还要移动指针,添加删除的操作LinkedList优于ArrayList,ArrayList还要移动数据

9. 慎用异常

当创建一个异常时,需要收集一个栈跟踪(stack track),这个栈跟踪用于描述异常是在何处创建的。构建这些栈跟踪时需要为运行时栈做一份快照,正是这一部分开销很大。当需要创建一个 Exception 时,JVM 不得不说:先别动,我想就您现在的样子存一份快照,所以暂时停止入栈和出栈操作。栈跟踪不只包含运行时栈中的一两个元素,而是包含这个栈中的每一个元素。

如果您创建一个 Exception ,就得付出代价,好在捕获异常开销不大,因此可以使用 try-catch 将核心内容包起来。从技术上讲,你甚至可以随意地抛出异常,而不用花费很大的代价。招致性能损失的并不是 throw 操作——尽管在没有预先创建异常的情况下就抛出异常是有点不寻常。真正要花代价的是创建异常,不应该不管三七二十一就抛出异常。异常是为异常的情况而设计的,使用时也应该牢记这一原则

10. SQL语言应尽量使用大写形式

在java+Oracle的应用系统开发中,java中内嵌的SQL语言应尽量使用大写形式,以减少Oracle解析器的解析负担。

11. 不要在循环中使用Try/Catch语句,应把Try/Catch放在循环最外层

12. array(数组)和ArrayList的使用

array 数组效率最高,但容量固定,无法动态改变,ArrayList容量可以动态增长,但牺牲了效率。

为什么一般都使用 List list = new ArrayList() ,而不用 ArrayList alist = new ArrayList()呢? 

那么为什么不List list; list=null;  list.add(123);?因为list是接口这样使用时错误的

方便以后扩展

List是一个接口,而ArrayList 是一个类。 ArrayList 继承并实现了List。
List list = new ArrayList();这句创建了一个ArrayList的对象后把上溯到了List。此时它是一个List对象了,有些ArrayList有但是List没有的属性和方法,它就不能再用了。而ArrayList list=new ArrayList();创建一对象则保留了ArrayList的所有属性。
为什么一般都使用 List list = new ArrayList() ,而不用 ArrayList alist = new ArrayList()呢? 
问题就在于List有多个实现类,如 LinkedList或者Vector等等,现在你用的是ArrayList,也许哪一天你需要换成其它的实现类呢?,这时你只要改变这一行就行了:List list = new LinkedList(); 其它使用了list地方的代码根本不需要改动。假设你开始用 ArrayList alist = new ArrayList(), 这下你有的改了,特别是如果你使用了 ArrayList特有的方法和属性。 如果没有特别需求的话,最好使用List list = new LinkedList(); ,便于程序代码的重构. 这就是面向接口编程的好处。

 

 

 

 

 

 

 

 

 

转载地址:http://fattf.baihongyu.com/

你可能感兴趣的文章
DAT_copy 产生的问题
查看>>
OV5620的视频驱动
查看>>
浏览器配置脚本的编写
查看>>
HTTP请求流程(一)----流程简介
查看>>
HTTP请求模型和头信息参考
查看>>
Http协议的Delete和Put方法是做什么的?怎么用?
查看>>
C++中两个类交叉定义或递归定义的解决办法
查看>>
String.format详解
查看>>
JSONObject、JSONArray
查看>>
JSON parse 错误: unexpected token at分析和解决
查看>>
python built-in function summary
查看>>
对于git/热部署/创建maven工程的小记录
查看>>
在jsp中调用本地外部json文件的解决方法
查看>>
ECharts is not Loaded解决方案
查看>>
ECharts地图显示不完整,只显示南海诸岛问题
查看>>
echarts is not defined解决方案
查看>>
echarts切换tab时,第一个图表显示,第二个图表不显示的解决办法
查看>>
记一次Hive 行转列 引起的GC overhead limit exceeded
查看>>
Scala List的一些常用方法
查看>>
FastJson对JSON字符串、JSON对象及JavaBean之间的相互转换
查看>>