java list大資料量用addAll
問題是這樣產生的,網上一哥們發了一個面試題:
ListA 裡面有 1 2 3
ListB裡面有 4 5 6
讓ListA變成 1 2 3 4 5 6
我覺得很簡單 ,就說用for迴圈遍歷 新增就好了。結果面試官說
答案是使用addAll方法,因為這樣效率高:
我表示很費解,於是查閱了資料。
得出以下結論:
在小資料量時,for迴圈效率高,大資料量時addAll方法效率高:
原因如下:
ArrayList的addAll的實現為:
[java] view plaincopy
- public boolean addAll(Collection c) {
- Object[] a = c.toArray();
- int numNew = a.length;
- ensureCapacity(size + numNew); // Increments modCount
- System.arraycopy(a, 0, elementData, size, numNew);
- size += numNew;
- return numNew != 0;
- }
很顯然。。在拷貝陣列時使用了
arraycopy 這個方法。這個方法是使用拷貝記憶體的做法 ,效率比遍歷陣列塊很多。
首先找到資料來源 然後將該段記憶體拷貝。
當然值得注意的是,這個函式中還使用了toArray方法,這個方法是 要遍歷操作的
但是如果需要多次遍歷,那麼addAll還是在效能上會獲取優勢的. .
下面是網上的一個測試 在20組資料時 還是 for效率高,但是在大資料量的時候 arraycopy 方法就明顯佔優勢了。
http://www.exam8.com/computer/djks/dj2/Java/ziliao/200810/1314435.htmlhttp://www.exam8.com/computer/djks/dj2/Java/ziliao/200810/1314435.html
另外:
arraycopy的定義是這樣的
public static native void arraycopy(Object src, int srcPos, Object dest, int destPos,int length);
native關鍵字的意思是 這個函式的原始碼在JDK中沒有的。但是他呼叫的是本地計算機中的函式
這個函式是C,或者C++寫完的,編譯成DLL。 java呼叫。所以效率比for迴圈要塊。
綜上所述 :為什麼在大資料量時使用addall方法效率快?
1.使用記憶體拷貝,移動資料。
2.本地函式,執行效率高。
那小資料量時呢?
以上2點都不明顯,並且首先要呼叫toArray方法,在小資料量時,效果沒有for來的好。