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

欢迎!有关如何使用本站的信息,请参阅关于页面。

0 投票
Collections

(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

在ATransientSet.conj中添加包含性检查可以使行为保持一致并通过附加的测试,但我认为这可能会造成性能下降。有什么看法吗?

0 投票

评论由:michaelblume 撰写

附加的提议修复方案 -- 注意这可能对瞬态集造成性能下降。

0 投票

评论由:michaelblume 撰写

附加一个替代修复方案 -- 而不是在每次瞬态康尼中进行包含性检查,使用back set.get和entryAt。更具有侵略性,但可能更快。

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