1,000,000 回 assoc! を transient な map に行ったけど、 8 個しか値が入っていないのは何故?
興味深かった。ベクターに対して同様のことを行った場合は期待通りに動くけど、マップに対してだと動かないという例。
(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! の実装が新しい map を返すようになっているからなんだよ( transient のままではあるけど)。というもの。
詳しくは ClojureDoc にいい具体例が書いてあるから参照してくれと。
assoc! - clojure.core | ClojureDocs - Community-Powered Clojure Documentation and Examples
ちなみになんで 8 なのかというと、 Clojure は内部的に PersistentArrayMap と PersistentHashMap を使い分けていて、 8 個くらいまでは前者を使うけどそれ以上は後者を使うかららしいとのこと。