java基本优化方法总结

来源:互联网 发布:深圳中广核设计院 知乎 编辑:程序博客网 时间:2024/05/21 04:01

java代码优化

1、循环

通常把大循环放在里面,把小循环放在外面,例如:

[java] view plaincopy
  1. for(int i=0; i<10;i++) 
  2.     for(int j=0; j<1000000;j++) 
  3.     {  
  4.             ... 
  5.     } 
把与循环index不相关的移到循环的外面,例如:

[java] view plaincopy
  1. for(int i=0; terminal=x.length;i<terminal;i++) 
  2. {x = x/scaleA * scaleB;} 
  3. //应该该成: 
  4. Double scale = scaleB*scaleA; 
  5. for(int i=0; terminal=x.length;i<terminal;i++) 
  6. {x = x/scale ;} 
在重要的循环里,消除循环终止判断时的方法调用,例如:
[java] view plaincopy
  1. for(int i=0; i<collection.size();i++) 
  2. { ... } 
  3. //尽量减少对变量的重复计算 
  4. for(int i=0; n=collection.size();i<n;i++) 
  5. {...} 
尽量不要在循环中使用
[java] view plaincopy
  1. Try { 
  2. } catch() { 

      应把其放置在最外层

循环内不要创建大量的临时变量

[java] view plaincopy
  1. for(int i=1;i<=domainCount;i++){ 
  2.         ...  
  3.        AuditResult auditResult =new AuditResult(); 
  4.         ... 
  5. //这种做法会在内存中保存N份这个对象的引用,会浪费大量的内存空间,改为 
  6. AuditResult auditResult; 
  7. for(int i=1;i<=domainCount;i++){ 
  8.         ...  
  9.        auditResult=new AuditResult(); 
  10.         ... 
2、字符串

     ■ 消除字符串连接

  ■创建长字符串时,总是使用StringBuffter代替String

  ■预先分配StringBuffer空间 StringBuffer sb = new StringBuffer(5000);

    ■ StringBuffer 和StringBuilder的区别:

java.lang.StringBuffer线程安全的可变字符序列。一个类似于String 的字符串缓冲区,但不能修改。

    StringBuilder,与该类相比,通常应该优先使用java.lang.StringBuilder类,因为它支持所有相同的操作,但由于它不执行同步,所以速度更快。

3、异常

        ■ 异常只用于单个真正的错误条件,抛出一个异常和执行一个catch代码块花费是很高的(主要由于当创建一个异常时要获得线程栈的一个快照),只当条件真的异常时才抛出一个异常

  ■ 抛出异常首先要创建一个新的对象。

  Throwable接口的构造函数调用名为fillInStackTrace()的本地(Native)方法,fillInStackTrace()方法检查堆栈,收集调用跟踪信息。

  只要有异常被抛出,JVM就必须调整调用堆栈,因为在处理过程中创建了一个新的对象。

  异常只能用于错误处理,不应该用来控制程序流程。

  ■使编译器和运行时最优化,将几个方法调用放在一个try/catch块中,而不是为每个方法调用实现几个try/catch块,例如:

[java] view plaincopy
  1. try{  
  2.     Some.method1(); //Difficut for java1.4  
  3. }catch(method1Exception e){  
  4.     handle exception 1 // to optimize this code 
  5. try{  
  6.     Some.method2(); //Difficut for java1.4  
  7. }catch(method2Exception e){  
  8.     handle exception 2 // to optimize this code 
  9. try{  
  10.     Some.method3(); //Difficut for java1.4  
  11. }catch(method3Exception e){  
  12.     handle exception 3 // to optimize this code 
  13. //应该写为: 
  14. try{  
  15.     //Difficut for java1.4  
  16.     Some.method1();  
  17.     Some.method2();  
  18.     Some.method3();  
  19. }catch(method1Exception e){  
  20.     handle exception 1  
  21. }catch(method2Exception e){  
  22.     handle exception 2  
  23. }catch(method3Exception e){  
  24.     handle exception 3  

4、尽量指定类的final修饰符

         ■带有final修饰符的类是不可派生的。在Java核心API中,有许多应用final的例子,例如java.lang.String。其为String类指定final也防止了人们覆盖length()方法。

  另外,如果指定一个类为final,则该类所有的方法都是final。Java编译器会寻找机会内联(inline)所有的final方法(这和具体的编译器实现有关)。此举能够使性能平均提高50%。

5、尽量使用局部变量

         ■调用方法时传递的参数以及在调用中创建的临时变量都保存在栈(Stack)中,速度较快。其他变量,如静态变量、实例变量等,都在堆(Heap)中创建,速度较慢。另外,依赖于具体的编译器/JVM,局部变量还可能得到进一步优化

6、乘法和除法

[java] view plaincopy
  1. for (val =0; val <100000; val +=5) {  
  2.     alterX = val * 8;  
  3.     myResult = val * 2
  4. //优化后: 
  5. for (val =0; val <100000; val +=5) {  
  6.     alterX = val << 3;  
  7.     myResult = val << 1
这个还需要看具体情况,并不是所有的乘除法都能这样优化。

7、array(数组) 和 ArrayList的使用

    array([]):最高效;但是其容量固定且无法动态改变;

    ArrayList:容量可动态增长;但牺牲效率;

    基于效率和类型检验,应尽可能使用array,无法确定数组大小时才使用ArrayList。

    ArrayList内部封装了一个Object类型的数组,从一般的意义来说,它和数组没有本质的差别,甚至于ArrayList的许多方法,如Index、IndexOf、Contains、Sort等都是在内部数组的基础上直接调用Array的对应方法。

8、在JAVA + ORACLE的应用系统开发中,java中内嵌的SQL语句尽量使用大写的形式,以减轻ORACLE解析器的解析负担

9、由于JVM的有其自身的GC机制,不需要程序开发者的过多考虑,从一定程度上减轻了开发者负担,但同时也遗漏了隐患,过分的创建对象会消耗系统的大量内存,严重时会导致内存泄露,因此,保证过期对象的及时回收具有重要意义。JVM回收垃圾的条件是:对象不在被引用;然而,JVM的GC并非十分的机智,即使对象满足了垃圾回收的条件也不一定会被立即回收。所以,建议我们在对象使用完毕,应手动置成null,这样也可以提供性能。

10、尽量采用lazy loading 的策略

即在需要的时候才开始创建,例如:

[java] view plaincopy
  1. String str = “aaa”;  
  2. if(i ==1) { 
  3.     list.add(str);  
  4. //应替换为: 
  5. if(i ==1)  
  6.     String str = “aaa”;  
  7.     list.add(str);  
  8. }  

11、在使用同步机制时,应尽量使用方法同步代替代码块同步

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

0 0