链表快还是数组快?

2022-04-18 10:11:51 +08:00
 3dwelcome
最近在 B 站看一些 C++并发教学视频,我发现在服务器很多算法里,非常喜欢用链表。

然而由于现代 CPU 设计高速缓存的原因,我网上查性能对比环节,几乎 90%情况下,都是数组性能比链表好。



https://dzone.com/articles/c-benchmark-%E2%80%93-stdvector-vs

那么问题来了,是不是书本上链表算法已经过时,大部分情况下,用数组替代会更好一些呢?
7879 次点击
所在节点    算法
67 条回复
lifanxi
2022-04-19 09:03:11 +08:00
@3dwelcome
你似乎有个误解,认为 std::vector 可以通过拼接串联小数组的方式来进行优化,减少扩容时复制数据的开销,但这是不对的,C++标准上强要求 std::vector 的内存必须是连续的。如果不连续,它就不叫“数组”,也不叫“std::vector”。

为了保证这个连续性,所以数组或 std::vector 在插入数据或扩容时,势必需要进行数据复制,这在数据量大 /对象复杂的时候有不可忽略的性能开销。

所以其实你贴的文章中说得很清楚,在多插入场景下,std::vecotr 只有在非常小数据量的情况下,性能才比 std::list 要好。这一点无论从理论上还是实践中都可以得到证实。

在实际开发中,是不是因为自己的场景下数组比链表快那么一点点就一定要用数组呢?我觉得不对的。写代码时更多要考虑代码所要表达的思想,如果你代码的逻辑是一个典型的链表更优场景,就应该在代码中用链表。这样的代码长远来看才更好维护。如果确实为了极致性能想改成用数组,也需要加注释保证以后别人在数据集变大遇到性能问题时可以及时定位,甚至加 fallback 逻辑自动保证在大数据集情况下不会带来严重的性能回退。
summerLast
2022-04-19 09:30:41 +08:00
@3dwelcome 数组是连续的,计算机架构里面有用空间换时间的多级 cache ,整块的空间更容易被 cache 提高命中率,其中的关键是 cache 和 内存的访问速度不是一个数量级,数组更容易被 cache , 如果没有 cache 或数组较大时链表插入更优秀
summerLast
2022-04-19 09:31:09 +08:00
@summerLast 内存空间连续的
ExplorerLog
2022-04-19 09:40:07 +08:00
std::array
std::vector
std::list
3dwelcome
2022-04-19 09:52:56 +08:00
@lifanxi “你似乎有个误解,认为 std::vector 可以通过拼接串联小数组的方式来进行优化”

不以长短论英雄。缝合小数组(deque)也是数组里的一个分支。

13cm 和 18cm 哪个更强?不好说的。

链表还有一个最大的问题,是不好维护。你数组还能设个越界报错,新手链表用不好,指针就在天上乱飞。
xtinput
2022-04-19 14:32:52 +08:00
内存读写速度成倍提升,CPU 运算速度增长缓慢
数组慢的地方是增删,增删主要是内存读写
高频增删用链表
高频读取用数组
stuazt
2022-09-05 16:04:27 +08:00
链表快还是数组快。。。这个学算法和数据结构的时候,不是 101 问题吗

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/847588

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX