java程序性能优化

来源:互联网 发布:彩虹代刷网源码2.0 编辑:程序博客网 时间:2024/06/01 08:15
1,使用'system.arraycopy ()'代替通过来循环复制数组 
void method () {
       int[] array1 = new int [100];
       for (int i = 0; i < array1.length; i++) {
           array1 [i] = i;
       }
       int[] array2 = new int [100];
       System.arraycopy(array1, 0, array2, 0, 100);
       for (int i : array2)
       System.out.println(array2[i]);
   }


2,使用移位操作来代替'a / b'操作, 使用移位操作代替'a * b' 
 public void calculate(int a) {
        int mul = a << 2;  
        int mul2 = a << 3;
        int temp = a * 3;       // 不能转换
    }


3,不要在循环中调用synchronized(同步)方法 
不要在循环体中调用同步方法,如果必须同步的话,推荐以下方式: 
import java.util.vector;
public class syn {
    public void method (object o) {
    }
private void test () {
    synchronized{//在一个同步块中执行非同步方法
            for (int i = 0; i < vector.size(); i++) {
                method (vector.elementat(i));   
            }
        }
    }
    private vector vector = new vector (5, 5);
}
4,将try/catch块移出循环 
将try/catch块移出循环         
  
 void method (fileinputstream fis) {
        try {
            for (int i = 0; i < size; i++) {
                _sum += fis.read();
            }
        } catch (exception e) {}
    }


5,确定 stringbuffer的容量 
StringBuffer的默认容量为16,当StringBuffer的容量达到最大容量时,她会将自身容量增加到当前的2倍+2,也就是2*n+2。无论何时,只要StringBuffer到达她的最大
容量,她就不得不创建一个新的对象数组,然后复制旧的对象数组,这会浪费很多时间。所以给StringBuffer设置一个合理的初始化容量值,是很有必要的! 
为stringbuffer提供寝大小。         
public class rsbc {
    void method () {
        stringbuffer buffer = new stringbuffer(max);
        buffer.append ("hello");
    }
    private final int max = 100;
}
StringBuffer,StringBuilder 的区别在于:java.lang.StringBuffer 线程安全的可变字符序列。一个类似于String的字符串缓冲区,但不能修改。StringBuilder与该类
相比,通常应该优先使用 StringBuilder类,因为她支持所有相同的操作,但由于她不执行同步,所以速度更快。为了获得更好的性能,在构造StringBuffer或 
StringBuilder时应尽量指定她的容量。当然如果不超过16个字符时就不用了。 
相同情况下,使用StringBuilder比使用 StringBuffer仅能获得10%~15%的性能提升,但却要冒多线程不安全的风险。综合考虑还是建议使用StringBuffer。 

6,与一个接口 进行instanceof操作 
基于接口的设计通常是件好事,因为它允许有不同的实现,而又保持灵活。只要可能,对一个对象进行instanceof操作,以判断它是否某一接口要比是否某一个类要快。 
例子: 
public class insof {
    private void method (object o) {
        if (o instanceof interfacebase) { }  // better
        if (o instanceof classbase) { }   // worse.
    }
}


7,尽量使用final修饰符。 

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


8,不用new关键字创建对象的实例。 

用 new关键词创建类的实例时,构造函数链中的所有构造函数都会被自动调用。但如果一个对象实现了Cloneable接口,我们可以调用她的clone() 方法。clone()方法不
会调用任何类构造函数。 
下面是Factory模式的一个典型实现。 
public static Credit getNewCredit()
{
    return new Credit();
}
改进后的代码使用clone() 方法, 
private static Credit BaseCredit = new Credit();
public static Credit getNewCredit()
{
    return (Credit)BaseCredit.clone();
}

9.HaspMap的遍历。 
Map<String, String[]> paraMap = new HashMap<String, String[]>();
for( Entry<String, String[]> entry : paraMap.entrySet() )
{
    String appFieldDefId = entry.getKey();
    String[] values = entry.getValue();
}
利用散列值取出相应的Entry做比较得到结果,取得entry的值之后直接取key和 value。 

10, System.out.println(Long.toHexString(0x100000000L + 0xcafebabe));// cafebabe  
为了执行该计算,Java将int类型的数值用拓宽原生类型转换提升为long类型,然后对两个long类型数值相加。因为
int是有符号的整数类型,所以这个转换执行的是符号扩展。
这个加法的右操作数0xcafebabe为32位,将被提升为long类型的数值0xffffffffcafebabeL,之后这个数值加上了左操
作0x100000000L。当视为int类型时,经过符号扩展之后的右操作数的高32位是-1,而左操作数的第32位是1,两个数
值相加得到了0:
  0x 0xffffffffcafebabeL
+0x 0000000100000000L
-----------------------------
 0x 00000000cafebabeL
如果要得到正确的结果0x1cafebabe,则需在第二个操作数组后加上“L”明确看作是正的long型即可,此时相加时拓
展符号位就为0:
窄数字类型提升至宽类型时使用符号位扩展还是零扩展
byte是有符号的类型
char型提升到其他类型,所以采用零扩展而不是符号扩展
http://jiangzhengjun.iteye.com/blog/652623
原创粉丝点击