Scala List
中的结构共享非常简单易懂。但Scala Vector
是一个比列表更复杂的数据结构。如何在Scala中实现结构共享Vector
?
答案 0 :(得分:10)
Vector基本上是一个树(trie),每个级别都有32个分支。例如,如果你有一个Vector,例如3000个元素,你想索引元素2045,例如,它转换为二进制的100000010101
,它会将它分解为5位块,用作树的索引: 10
(即2)在第一个分支中然后00000
(即0)在下一个,最后10101
(即21)在终端分支中,然后是数据。 / p>
鉴于这种结构,很容易看出如何在结构上共享内容:您可以共享任何未更改的子树。因此,如果使用不同的元素2045创建一个新向量,则必须更改并非所有3000个元素,而是重新创建“仅”三个大小为32的数组:终端一被替换为更新元素21的副本;那么它的父母必须被索引0中这个新孩子的副本所取代;那么它的父元素必须用索引2中的正确子树替换。
现在,只要你的向量中有超过32个元素,这就提供了很多结构共享,但它仍然是一个相当大的开销。因此,向量末尾的添加是特殊的,因此您只需添加到现有数组。旧的Vector仍然指向那个数组,但是他们认为结束时间较早(并且该部分没有变化)所以它可以正常工作。
有一个更复杂但相似的方案允许以类似的方式在向量的前面添加(基本上,通过在前面留空间并且除了索引方案之外还通过索引和偏移来跟踪指向的位置)
虽然实现的技巧不允许交替添加正面和背面,但是每次添加都会有效地重建树。制作具有更好结构共享的版本是可能的,但访问可能会慢一些。