什么时候链表比循环缓冲区更受欢迎?
When would a linked list be preferred over a circular buffer?
就big-O运行时而言,似乎两种数据结构在"average"情况下都有:
O(1)
insertion/removal 进入开始和结束
O(n)
insertion/removal 到任意索引
O(1)
查找开始和结束
循环缓冲区的优点:
O(1)
查找而不是某些任意索引 O(n)
- 不需要创建节点,因此不需要在每次插入时动态分配
- 由于缓存预测更好,遍历速度更快
- 由于向量化(例如使用
memmove
)填补空白,移除速度更快
- 通常需要更少space(因为在链表中,对于每个节点,您必须对指向下一个 and/or 前一个节点的指针进行排序)
链表的优点:
- 更容易
O(1)
insertion/removal 到达某个特定位置(例如,可以在链接列表的中途获得它)。循环缓冲区可以做到,但比较复杂
O(1)
在最坏的情况下插入,不像循环缓冲区 O(n)
(当它需要增加缓冲区时)
基于此列表,在我看来,循环缓冲区几乎在所有情况下都是更好的选择。我错过了什么吗?
MCS 锁是目前最具扩展性的锁设计之一。线程使用原子比较和交换来尝试获取锁。如果可行,就完成了。如果它不起作用,线程将使用原子交换将自己排在等待者列表的尾部。
没有办法用没有锁的循环缓冲区或更复杂的原子指令使用来做类似的事情。
就big-O运行时而言,似乎两种数据结构在"average"情况下都有:
O(1)
insertion/removal 进入开始和结束O(n)
insertion/removal 到任意索引O(1)
查找开始和结束
循环缓冲区的优点:
O(1)
查找而不是某些任意索引O(n)
- 不需要创建节点,因此不需要在每次插入时动态分配
- 由于缓存预测更好,遍历速度更快
- 由于向量化(例如使用
memmove
)填补空白,移除速度更快 - 通常需要更少space(因为在链表中,对于每个节点,您必须对指向下一个 and/or 前一个节点的指针进行排序)
链表的优点:
- 更容易
O(1)
insertion/removal 到达某个特定位置(例如,可以在链接列表的中途获得它)。循环缓冲区可以做到,但比较复杂 O(1)
在最坏的情况下插入,不像循环缓冲区O(n)
(当它需要增加缓冲区时)
基于此列表,在我看来,循环缓冲区几乎在所有情况下都是更好的选择。我错过了什么吗?
MCS 锁是目前最具扩展性的锁设计之一。线程使用原子比较和交换来尝试获取锁。如果可行,就完成了。如果它不起作用,线程将使用原子交换将自己排在等待者列表的尾部。
没有办法用没有锁的循环缓冲区或更复杂的原子指令使用来做类似的事情。