为什么链表结构数据不容易被被缓存命中?

1. 链表的内存存储方式

  • 链表的非连续内存分配:在链表中,每个节点包含了数据和指向下一个节点的指针(对于双向链表,还包括指向上一个节点的指针)。这些节点在内存中并不是连续存储的,可能分布在不同的内存位置。
  • 指针跳跃访问:由于链表节点分散存储,CPU 访问一个节点时需要通过指针跳转到下一个节点,导致访问时无法利用 CPU 的缓存局部性(cache locality)。而数组中的元素是按顺序存储的,CPU 在访问时可以预加载相邻元素,从而提高缓存命中率。

2. CPU 缓存与局部性原理

  • 缓存局部性:CPU 在执行程序时会预取接下来的数据,特别是当程序按顺序访问内存时,CPU 会尽量将接下来的数据提前加载到高速缓存中。连续的内存块会增加缓存命中的概率,因为它们存储在相邻的内存位置,易于被一起加载到缓存中。
  • 链表的指针跳跃与缓存不匹配:由于链表中的元素分散存储,CPU 在访问链表时无法通过顺序的内存访问来提升缓存命中率。例如,当访问链表的一个节点时,CPU 需要加载当前节点的数据,然后通过指针去查找下一个节点的内存地址,这种跳跃式的访问使得 CPU 无法有效地预加载下一个节点的数据,进而导致缓存未命中。

3. CPU 缓存的缓存行(Cache Line)

  • 缓存行的概念:现代 CPU 的缓存系统是按“缓存行”来组织的,通常每个缓存行的大小是 64 字节。数组元素是连续存储的,因此一旦加载到缓存行中,紧随其后的元素也很可能已经被加载到缓存中,进而提高了连续访问的效率。
  • 链表的访问模式与缓存行不匹配:链表元素是分散存储的,访问一个节点时,可能会导致 CPU 从不同的内存地址加载数据,这就无法有效利用缓存行的优势。尤其是当链表节点存在于不同的内存页或缓存行时,缓存的有效性就大大降低。

参考文献:

  1. Java Collections Framework - LinkedList
  2. Why Linked List is slower than Array
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值