非删除头部尾部的情况下,LinkedList和ArrayList性能对比

学过数据结构的都知道,理论上,链表相比数组在删除方面更加有优势,原因在于数组在删除后,需要将删除位置后面的元素都向前移动一位。但是如果是指定删除第几个元素(如删除位置处于整个数组的中间)的情况下就不一样了。测试代码如下

public class test {
    public static void main(String[] args) {
        ArrayList list = new ArrayList();
        for(int i = 0 ; i < 100000;i++){
            list.add(i);
        }
        int n =list.size();
        long time1 = System.currentTimeMillis();
        while (!((n--)==0)){
            list.remove(n/2);
        }
        long time2 = System.currentTimeMillis();
        System.out.println(time2-time1+"ms");
    }
}

最后测试结果如下:

Linklist代码:

public class test {
    public static void main(String[] args) {
        LinkedList list = new LinkedList();
        for(int i = 0 ; i < 100000;i++){
            list.add(i);
        }
        int n =list.size();
        long time1 = System.currentTimeMillis();
        while (!((n--)==0)){
            list.remove(n/2);
        }
        long time2 = System.currentTimeMillis();
        System.out.println(time2-time1+"ms");
    }
}

 测试结果:

 

分析原因:

ArrayList中remove方法中,有源码如下:

private void fastRemove(Object[] es, int i) {
    modCount++;
    final int newSize;
    if ((newSize = size - 1) > i)
        System.arraycopy(es, i + 1, es, i, newSize - i);
    es[size = newSize] = null;
}

可见调用了System.arraycopy方法()进行了删除元素后的,元素向前移位操作。

而LinkedList 查找被删除的节点代码如下:

Node<E> node(int index) {
    // assert isElementIndex(index);

    if (index < (size >> 1)) {
        Node<E> x = first;
        for (int i = 0; i < index; i++)
            x = x.next;
        return x;
    } else {
        Node<E> x = last;
        for (int i = size - 1; i > index; i--)
            x = x.prev;
        return x;
    }
}

  分析原因为System.arraycopy这个方法是个native方法,性能优良,以下文章有进行测试,

Java性能漫谈-数组复制之System.arraycopy - yakovchang - 博客园 (cnblogs.com)icon-default.png?t=M0H8https://www.cnblogs.com/yakovchang/p/java_system_arraycopy.html       推断由于是array是个连续数组,可放入cpu的缓存中,因此访问速度会快很多,而相比之下LinkedList存储比较零散,需要多次访存,且本身的结构也比较复杂,因此不用位移元素的优势被完全抵消了。

结论,如果大部分操作都是在数组中间进行删除和增加,而不是头插,使用ArrayList会获得更好的性能。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值