这二者的区别 主要从以下几个方面入手
- 1.底层实现的数据结构
- 2.随机访问的效率对比
- 3.增加删除的效率对比
- 4.内存消耗
- 5.cpu缓存和局部原理
1.底层实现的数据结构
ArrayList集合底层采用的是基于数组的方式进行存储的,而linkedlist底层则是基于双向链表进行存储
2.随机访问的效率对比
首先解释下什么是随机访问,随机访问就是通过索引进行元素的查找访问。而查询代表的是指通过内容去查找相对应的位置,所以就查询而言,他们俩都需要进行全部遍历,所以时间复杂度都是O(n)。
由于ArrayList是基于数组实现的,所以他的内存空间是连续的,可以通过首地址而算出所有元素所对应的值,所以ArrayList可以直接通过下标进行随机访问,速度十分快
而linkedlist是基于链表的结构,内存存储不连续,今儿不能进行下标访问,所以要进行 遍历,进而效率要比ArrayList要低
3.增加删除的效率对比
我们可以从三个方面进行分析,1.头部的插入和删除。2.中间的插入和删除。3.尾部的插入和删除
第一,头部的增加和删除。对于ArrayList来说,头部添加或删除一个元素会移动数组后面的元素,进而造成效率低。对于LinkedList来说的话,就不需要考虑移动元素这些,只需要把指针重新该一下就可以,效率会比ArrayList高
第二,中间的插入和删除。对于ArrayList来说,即使是中间的插入还是删除,还是需要耗费性能去挪动数据。但效率却普遍比LinkedList要高,可能很多人不理解,为什么链表的插入删除操作效率还比数组低。 因为LinkedList在真正进行删除和添加该元素的前提是得找到该元素,而LinkedList是链表实现的,所以只能进行遍历才能找到该元素,进而进行插入或者删除操作,而ArrayList可以直接通过下标进行位置查找,所以性能要比LinkedList要高
第三,尾部的插入和删除。对于ArrayList来说尾部进行插入和删除操作,并不需要对原有的元素进行挪动,只有在数组需要扩容时,进行新旧数组的拷贝,但这点性能可以忽略不计,LinkedList对尾部的插入和删除可以说效率也是很高的,而数组进行该操作的效率和LinkedList差不多,甚至会超过LinkedList。
4.内存消耗
ArrayList由于是数组,每一个元素中只存储值,不会存储其他的变量,而LinkedList不仅要存储值,因为是双向链表,还要存储他的下一个元素的地址和上一个元素的地址。 所以LinkedList比ArrayList需要更多的内存消耗
5.cpu缓存和局部原理
这个就简单说说
首先什么是cpu缓存,作用是什么。
我们在软件中的所敲的代码,其中的变量这些的运算,是由底层的cpu进行运算。都知道cpu计算是非常快的,但是在cpu读取内存中那些变量的过程 对比计算是非常慢的,相同,将计算的结果返回到内存中也是比较慢的。进而降低了cpu总体的性能。而cpu缓存就来了,cpu缓存就是 cpu和内存之间数据交换的一个媒介,里面缓存需要计算的变量。cpu缓存又分三级这个不多说。现在只需要知道cpu缓存是为了能更好的让内存和cpu进行数据的传递。效率更高。
现在来说说 cpu缓存大概是如何提高性能。首先CPU缓存也会去内存把需要的变量的值拿过来,这一步是没有任何节省时间的,但当该变量的值存进CPU缓存中时,下一次在用到该值就不需要再去内存中读取,就可以直接从CPU缓存中拿来用,同时CPU拿到CPU缓存里的值,计算完也是写入CPU缓存,等待CPU缓存集合起来一起返还给内存,这就是节省时间的原因。
再来说说局部原理
当内存向cpu缓存中存储数据时,内存会把需要的数据,以及该数据的地址相邻的数据一同存到cpu缓存中。
由于数组是连续存储的,所以,当我们使用其中某一个,其相邻的数据也都会存到cpu缓存里面,当我们下次用到另外的数据,cpu缓存中极有可能已经存如该值,进而提高性能。
而链表,内存空间不连续,所以存储的时候,如果每个元素离得远,就不会轻易一起存储再cpu缓存中,当访问下一个时,也会重内存中重新读取到cpu缓存中。
总结:
ArrayList充分利用了局部原理的作用,提高性能。而LinkedList并没有。
开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 8 天,点击查看活动详情