繁体   English   中英

数组的不可变数据结构替换

[英]Immutable data structure replacement for arrays

当您需要具有最快访问/更新的不可变列表时,您会使用什么? 如果你必须从中间访问一个元素,LinkedList可能会很慢,而且创建和重新填充它是不可能的。 二叉树? 四叉树?

如果更新非常罕见(或者集合很小),那么在初始化之后不写入的数组是值得的。 在这些情况下,低得多的常数因子(时间和空间)都超过线性时间更新。

除此之外,还有许多纯功能数据结构,为这些情况提供了更好的界限。 2-3个手指树(Haskell的Data.Sequence背后的数据结构)就是一个例子。 另一种选择是Clojure的向量和相关的数据结构(例如,轻松的Radix-Balanced Trees),它使用具有高扇出(32或更多)的树来保持读取便宜和结构共享以避免太多副本。

所有这些都是手动实现的中等技巧,特别是如果性能很重要,我不知道现有的实现(我不认为Clojure的向量是简单或方便从Java使用)。

我不确定我理解你在寻找什么,但我会尝试根据我在标准课程中看到的一些内容给出一些指示:

  • CopyOnWriteArrayList是一个可变但线程安全的列表,因为它在更新时复制了内部数组。 也许你可以从中调整一些想法,尽管对于大型列表来说显然效率不高。

  • ConcurrentHashMap在更复杂的结构上实现了类似的想法。 它将内部哈希表划分为单独的分区,因此更改只需要锁定对相关分区的访问权限。

    对于不可变列表,您可以执行类似的操作:将列表的内部数组划分为多个分区,并将它们全部视为不可变。 当您需要更改列表时,您只需要克隆一个分区和分区的索引,这比复制整个列表要便宜。

  • AWTEventMulticaster实现了类似的目标,但重复了绝对最小值。 这是一个聪明的二叉树。 查看来源

使用较小的内部分区或块,您可以获得更快的更新,但通常访问速度较慢。 使用更大的块(例如,整个阵列),您可以获得更慢的更新,但访问速度更快。

如果您确实需要最快的访问和更新,则必须使用可变数组。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM