【问题标题】:Erlang persistent data structuresErlang 持久化数据结构
【发布时间】:2016-08-02 11:44:40
【问题描述】:

据我了解,当您使用如下表达式创建新列表时,Erlang 不会复制 L1,它只会复制 H。

L2 = [H|L1]

Erlang 是否有针对dict 的持久数据结构(参见Persistent data structure),也就是说,当您在树中添加/删除/修改节点时,只有少数元素被复制(如Clojure)?

【问题讨论】:

    标签: clojure erlang


    【解决方案1】:

    您在使用[H|T] 构建列表时误解了这种情况。正如您所说,T 没有被复制,但H 也不是。所发生的只是一个新的列表单元被添加到T 前面,并引用H 作为其头部(它的尾部是T)。使用列表时,创建的唯一位是实际的列表单元格,而不是每个单元格中的数据。

    使用dict 时也会发生同样的情况。当您在dict 中修改(添加/删除元素)时,只会修改实际的dict 结构,而不会修改dict 中的实际数据。此外,只复制尽可能少的 dict 结构以进行修改也很聪明。

    所以,是的,Erlang 有持久的数据结构。在这方面,clojure 就像 Erlang(我们早在它之前就已经存在了)。

    【讨论】:

    • 好的,我们不会在这里讨论指针和值,区别对我来说很清楚,关键是如何使用具有持久性的大型内存键值存储(所以没有 ets)。我已经提到,在 clojure 中,在修改某些值期间,只有从根到该值的路径被复制(3-4 个节点),我们有两棵树:新树和旧树。我们如何在 erlang 中做到这一点?盒子中的某些结构是否实现了这种行为?
    • A = SomeTree, B = change(A). 你现在有了树 B 和树 A,其中 B 是新的,A 是旧的。使用 {A,B} 将两棵树放在同一个元组。这是你想知道的吗?
    • nop,我需要 A = SomeTree,B = change(A),并且 A 和 B 共享一些共同部分,请参阅 en.wikipedia.org/wiki/Purely_functional#Trees
    • 如果您重新阅读 rvirdings 的答案,您会看到:“它也很聪明,只复制尽可能少的 dict 结构以进行修改。”这就是你问的问题,你的问题确实复制错了,所以你似乎不太清楚 cons 单元格。答案是“是”,请读到最后。
    • 是的,Erlang 做的是纯功能树,只会修改从根到被修改节点的路径。 dict、gb_trees 和 array 库以这种方式工作。 lists 库也是如此,尽管它仅适用于列表。这是做事的标准方式,所以原则上所有处理数据结构的库都这样做。
    【解决方案2】:

    根据我的经验,库模块的数据结构在变大时不会降低性能或内存压力。

    对于 dict,它使用动态哈希表作为内部数据结构,并且工作基本上只在完成修改的存储桶上完成。

    我还查看了gb_trees 模块,在其中找到了评论:

    行为是对数的(应该如此)。

    而gb_trees 通常速度很快,所以我很确定不会进行太多复制。

    一般来说,如果你用像 Erlang 这样的语言来实现这样的数据结构,你会处理复制问题,所以对于一般的库函数就不用担心了。


    我重读了关于持久化数据结构的文章:在这篇文章的意义上,Erlang 的数据结构是完全持久化的,也是融合持久化的。

    【讨论】:

    • 那么线性结构呢?是否存在具有这些性能保证的向量(或集合)之类的东西?
    • 是的,有 .. 'array' 和 fwiw 'set' ... 你有没有尝试查看文档?
    猜你喜欢
    • 1970-01-01
    • 2017-09-03
    • 1970-01-01
    • 1970-01-01
    • 2013-04-17
    • 1970-01-01
    • 2019-03-13
    • 2011-03-24
    • 1970-01-01
    相关资源
    最近更新 更多