1. 程式人生 > >Arraylist 與 linkedlist新增資料速度測驗

Arraylist 與 linkedlist新增資料速度測驗

以下是測試程式碼

public class Main
{
	public static void main(String[] argv)
	{
		Test test = new Test();

		List<Integer> list = new LinkedList<>();
		long startTime = System.currentTimeMillis();
		System.out.println("linkeLIst" + Calendar.getInstance().getTime());
		test.listTest(list);
		System.out.println("linkeLIst" + Calendar.getInstance().getTime());
		long endTime = System.currentTimeMillis();
		System.out.println("linkedList  " + String.valueOf(endTime - startTime));

		List<Integer> list1 = new ArrayList<>();
		long startTime1 = System.currentTimeMillis();
		System.out.println("ArrayList" + Calendar.getInstance().getTime());
		test.listTest(list1);
		System.out.println("ArrayList" + Calendar.getInstance().getTime());
		long endTime1 = System.currentTimeMillis();
		System.out.println("ArrayList  " +  String.valueOf(endTime1 - startTime1));
	}
}
public class Test
{
	public void listTest(List<Integer> list)
	{
		Random random = new Random();
		for (int i = 1; i < 150000; i++)
		{
			list.add(0,i);
		}
	}
}

測試arraylit時會註釋掉linkedlist的程式碼,反之亦然。

測試結果發現,入門教材上說的arrayList增刪速度比linkedList速度快是不完全正確的。插入的位置越是靠前linkedList的優勢就越明顯。速度是arrayList  10倍左右(這裡的測試資料是15000)。並且資料量越大,插入資料的位置越靠前,差距越明顯,arraylist比linkedList慢這個結論越正確。如果插入的位置是在末尾,則arraylist要比linkedList快數倍,這說明插入的位置很重要,如果只是末尾插入,則使用arraylist是最好的選擇

測試還發現,如果資料量小於10000。那麼arraylist的新增操作比linkedList還要快。無論是在什麼位置都是如此。這說明資料量不大的情況下arrayList的速度要優於linkedList。

以下是對arrayList和linkedList原始碼的個人理解

    public void add(int index, E element) {
        checkPositionIndex(index);

        if (index == size)
            linkLast(element);
        else
            linkBefore(element, node(index));
    }

上面這樣一段是linkedList的在指定的位置插入資料的原始碼。首先檢查索引位置,找到要插入資料的位置的指標。然後判斷是在末尾插入還是在其他位置插入。這樣一來,每次做新增操作都是需要搜尋指標位置。再進行插入操作,當資料量小的時候也是如此,這也是資料量小時,速度比arraylist還要慢的原因

    public void add(int index, E element) {
        rangeCheckForAdd(index);

        ensureCapacityInternal(size + 1);  // Increments modCount!!
        System.arraycopy(elementData, index, elementData, index + 1,
                         size - index);
        elementData[index] = element;
        size++;
    }

以上這段是arraylist的原始碼。rangeCheckForAdd(index)先檢查插入的範圍。ensureCapacityInternal再確定是否超出陣列的長度。然後執行陣列拷貝的語句。如果超出現有陣列大小,則申請開闢新的記憶體空間(此處是時間開銷最大的部分)。然後再拷貝陣列,最後在新陣列指定的位置做賦值操作,並且陣列大小+1。

結論:資料量小,沒有超過arraylist陣列的上限,並且重新申請的記憶體空間不大,則速度上arraylist要比linkedList要快。如果資料量大,需要申請的記憶體空間越大,速度上arraylist就要比linkedList越慢。