2024 Clojure状态调查!中分享您的想法。

欢迎!请参考关于页面以获取更多关于如何使用本站的信息。

0
集合

(let [s (-> #{}
          transient
          (conj! (clojure.core/with-meta [-7] {:mynum 0}))
          (conj! (clojure.core/with-meta [-7] {:mynum -1}))
          persistent!)]
  [(meta (s [-7])) (meta (first s))])
=> [{:mynum -1} {:mynum 0}]


基本上,"key"(通过在集合上迭代获得的值)保留了第一个 conj! 的元数据,而"value"(通过调用 invoke 使用 "key" 获得的值)携带第二个 conj! 的元数据。这种行为与不使用瞬态时不同。


(let [s (-> #{}
          (conj (clojure.core/with-meta [-7] {:mynum 0}))
          (conj (clojure.core/with-meta [-7] {:mynum -1})))]
  [(meta (s [-7])) (meta (first s))])
=> [{:mynum 0} {:mynum 0}]


(在尝试 zach tellman 的 collection-check 时找到)

5 个答案

0

评论由:michaelblume 发布

附带展示问题的补丁(非修复方案)

0

评论由:michaelblume 发布

进一步调查

“keys”和“vals”之间的差异源于Clojure集合在底层使用映射。

持久性和瞬态之间的区别似乎是因为 PersistentHashSet 的 cons 方法在 contains 上做了短路处理(https://github.com/clojure/clojure/blob/clojure-1.6.0/src/jvm/clojure/lang/PersistentHashSet.java#L97),而 ATransientSet 的 conj 方法没有(https://github.com/clojure/clojure/blob/clojure-1.6.0/src/jvm/clojure/lang/ATransientSet.java#L27)。

将 contains 检查添加到 ATransientSet 的 conj 方法可以使行为一致,并通过了附加的测试,但我认为这可能会对性能产生负面影响。你的看法是什么?

0

评论由:michaelblume 发布

附加了提出的修复方案 — 注意这可能会对瞬态集合的性能产生负面影响。

0

评论由:michaelblume 发布

附加了一个替代的修复方案 — 而不是在每个瞬态 conj 上执行 contains 检查,改为使用 entryAt 返回 set.get。更具侵入性,但可能更快。

0
参考:[https://clojure.atlassian.net/browse/CLJ-1615](https://clojure.atlassian.net/browse/CLJ-1615) (由 michaelblume 报告)
...