扫描二进制搜索树与阵列

问题描述 投票:0回答:2

以什么方式在BST中找到一个元素(遍历)比在一个数组中线性扫描它要慢?

答案应该与缓存有关。有人可以解释这究竟是什么意思以及它为什么成立?

你是如何使用数组而不是使用BST缓存来“缓存这个”?

谢谢

arrays caching tree operating-system
2个回答
0
投票

我的猜测是使用BST并没有给你带来任何好处,因为,即使你正在缓存数据(这意味着存在某种类型的地点,你可以稍后访问相同的元素),插入操作和查找操作总是花费O(h),其中h是树的高度。在最坏的情况下,甚至是O(n)。

而使用数组进行缓存意味着当然首先它可能是线性的,但是无论何时访问数组中的相同元素,如果存在空间和时间局部性,您可能会发现自己直接访问相同的连续内存块,因为你已经知道它的索引,这意味着你有一个恒定的时间访问。


0
投票

我假设缓存涉及CPU缓存,它带有预取器,可预测您的下一次内存访问。因此,如果在数组中按顺序搜索,则预取程序会识别内存访问模式,并在CPU访问之前将内存加载到CPU缓存中。当CPU实际访问下一个存储器元素时,它已经在缓存中并且可以快速访问。如果没有缓存和预取程序,CPU将不得不等待内存控制器从RAM中获取数据,这与CPU缓存相比非常慢。

在BST中,您不进行顺序访问。在最坏的情况下,您的BST不驻留在连续的内存中,但每个节点都位于内存中的某个任意位置。你的预取器无法预测这一点。然后CPU必须等待从内存中提取每个元素。

虽然没有prefetchers,但是关于缓存行。在x86_64上,缓存行长度为64个字节。每个整数是4或8字节,因此您可以扫描每个缓存行的16或8个数组条目。第一次访问内存位置会获取整行,因此您只需为8次比较支付一次内存访问权限。对于BST,适用与上述相同的论点。节点内存可能不在同一个高速缓存行上,因此必须为每个比较进行内存访问。

总结一下:A)内存访问比比较需要更多的时间; B)如果通过数组或BST搜索更快取决于项目的数量。

© www.soinside.com 2019 - 2024. All rights reserved.