扫描二进制搜索树与数组

时间:2018-09-04 00:18:56

标签: arrays caching tree operating-system

  

在BST中找到一个元素(遍历)比在数组中线性扫描它要慢得多?

答案可能与缓存有关。有人可以解释一下这到底是什么意思以及为什么它成立吗?

您如何精确地使用数组而不是使用BST进行缓存?

谢谢

2 个答案:

答案 0 :(得分:0)

我的猜测是,使用BST不会给您带来任何好处,因为即使您正在缓存数据(这意味着存在某种局部性,例如以后您也可以访问同一元素),插入操作并且查找操作的总费用为 O(h),其中h是树的高度。在最坏的情况下,甚至 O(n)

使用数组进行缓存当然意味着一开始它可能是线性的,但是此后每当访问数组的同一元素时,如果存在空间和时间局部性,您可能会发现自己直接访问数组的相同块连续内存,因为您已经知道它的索引,这意味着您可以进行恒定时间访问。

答案 1 :(得分:0)

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

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

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

总结一下:A)内存访问比比较花费更多的时间; B)搜索数组或BST的速度更快取决于项目的数量。