作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
如果我尝试做 1000 000 assoc!
在 transient 向量上,我会得到一个包含 1000 000 个元素的向量
(count
(let [m (transient [])]
(dotimes [i 1000000]
(assoc! m i i)) (persistent! m)))
; => 1000000
(count
(let [m (transient {})]
(dotimes [i 1000000]
(assoc! m i i)) (persistent! m)))
; => 8
最佳答案
transient 数据类型的操作不保证它们将返回与传入的引用相同的引用。有时实现可能决定在 assoc!
之后返回一个新的(但仍然是 transient 的)映射。而不是使用您传入的那个。
ClojureDocs page on assoc!
有一个 nice example这解释了这种行为:
;; The key concept to understand here is that transients are
;; not meant to be `bashed in place`; always use the value
;; returned by either assoc! or other functions that operate
;; on transients.
(defn merge2
"An example implementation of `merge` using transients."
[x y]
(persistent! (reduce
(fn [res [k v]] (assoc! res k v))
(transient x)
y)))
;; Why always use the return value, and not the original? Because the return
;; value might be a different object than the original. The implementation
;; of Clojure transients in some cases changes the internal representation
;; of a transient collection (e.g. when it reaches a certain size). In such
;; cases, if you continue to try modifying the original object, the results
;; will be incorrect.
;; Think of transients like persistent collections in how you write code to
;; update them, except unlike persistent collections, the original collection
;; you passed in should be treated as having an undefined value. Only the return
;; value is predictable.
(count
(let [m (transient {})]
(persistent!
(reduce (fn [acc i] (assoc! acc i i))
m (range 1000000)))))
clojure.lang.PersistentArrayMap
(由数组支持的映射)用于具有 8 个或更少元素的映射。一旦超过 8,它就会切换到
clojure.lang.PersistentHashMap
.
user=> (type '{1 a 2 a 3 a 4 a 5 a 6 a 7 a 8 a})
clojure.lang.PersistentArrayMap
user=> (type '{1 a 2 a 3 a 4 a 5 a 6 a 7 a 8 a 9 a})
clojure.lang.PersistentHashMap
PersistentArrayMap
) 切换到哈希表 (
PersistentHashMap
),此时
assoc!
返回一个新的引用,而不是仅仅更新旧的引用。
关于dictionary - 为什么在 Clojure 的 transient 映射中插入 1000 000 个值会生成一个包含 8 个项目的映射?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29684803/
我有一个像这样的结构: struct S { data: i32, fun: Box, } 并希望使用编码器序列化数据部分。为此,我使用 rustc_serialize 并推导出它的特
我在 tomcat 中使用基于表单的身份验证,实际上我使用的是 j_security_check。代码如下 Login to the Tomcat-Demo applic
我是一名优秀的程序员,十分优秀!