天天看點

Java 4種數組複制方式的性能比較

package com.demo.main;

import java.util.Arrays;

/**
 * <ol>複制數組的4種方法
 * <li>for</li>
 * <li>clone</li>
 * <li>Arrays.copyOf(original, newLength)</li>
 * <li>System.arraycopy(src, srcPos, dest, destPos, length)</li>
 * </ol>
 */
public class ArrayCopyDemo {

    private static final byte[] buffer = new byte[*];
    static {
        for (int i = ; i < buffer.length; i++) {
            buffer[i] = (byte) (i & );
        }
    }
    private static long startTime;

    public static void main(String[] args) {
        startTime = System.nanoTime();
        methodFor();
        calcTime("methodFor");

        startTime = System.nanoTime();
        methodClone();
        calcTime("methodClone");

        startTime = System.nanoTime();
        methodArraysCopyOf();
        calcTime("methodArraysCopyOf");

        startTime = System.nanoTime();
        methodSystemArraycopy();
        calcTime("methodSystemArraycopy");
    }

    private static void methodFor() {
        byte[] newBuffer = new byte[buffer.length];
        for(int i=;i<buffer.length;i++) {
            newBuffer[i] = buffer[i];
        }
    }

    private static void methodClone() {
        byte[] newBuffer = buffer.clone();
    }

    private static void methodArraysCopyOf() {
        byte[] newBuffer = Arrays.copyOf(buffer, buffer.length);
    }

    private static void methodSystemArraycopy() {
        byte[] newBuffer = new byte[buffer.length];
        System.arraycopy(buffer, , newBuffer, , buffer.length);
    }

    private static void calcTime(String method) {
        long endTime = System.nanoTime();
        System.out.println(method + " cost " +(endTime-startTime)+ " nanosecond");
    }
}
           
Java 4種數組複制方式的性能比較

總結:

(1)從速度上看:System.arraycopy > clone > Arrays.copyOf > for

(2)for的速度之是以最慢是因為下标表示法每次都從起點開始尋位到指定下标處(現代編譯器應該對其有進行優化,改為指針),另外就是它每一次循環都要判斷一次是否達到數組最大長度和進行一次額外的記錄下标值的加法運算。

(3)檢視Arrays.copyOf的源碼可以發現,它其實本質上是調用了System.arraycopy。之是以時間差距比較大,是因為很大一部分開銷全花在了Math.min函數上了。

public static byte[] copyOf(byte[] original, int newLength) {
    byte[] copy = new byte[newLength];
    System.arraycopy(original, , copy, , Math.min(original.length, newLength));
    return copy;
}
           

(4)檢視System.arraycopy的源碼,可以發現它實質上是通過Jni調用本地方法,及c/c++已經編譯成機器碼的方法,是以快。

public static native void arraycopy(Object src,  int  srcPos,
                                        Object dest, int destPos,
                                        int length);
           

(5)clone的源碼不詳,鄙人無法比較,有知道的希望不吝賜教。