我有一个原子,
(def a (atom {:a <some-value>}))
并且它需要不断更新,从长远来看,最有效的内存是什么??
(swap! a assoc :a <next-value>)
或
(swap! a (fn [_] {:a <next-value>}))
直观地说,根据我在持久性结构上所听到的谈话,我认为第二种方式会慢一点,但从长远来看会更好......但是想要第二种意见。
答案 0 :(得分:4)
reset!
,而不是swap!
。swap!
函数来考虑旧值。答案 1 :(得分:0)
跟进Ankur的建议以及我的sigar analytics lib https://github.com/zcaudate/sigmund包装器的无耻插件我运行了一些快速和脏的诊断程序以进行更新和重置!
(ns test-memory
(:require [sigmund.core :as sig])
(:import java.lang.management.ManagementFactory))
(def counter (atom 0))
(def data (atom {:data {:a 0
:b 0}}))
(defn update-loop [a]
(swap! a update-in [:data :a] (fn [_] (Math/random)))
(swap! a update-in [:data :b] (fn [_] (Math/random)))
(swap! counter + 2)
(recur a))
(defn update-loop1 [a]
(reset! a {:data {:a (Math/random)
:b (:b (:data @a))}})
(reset! a {:data {:b (Math/random)
:a (:a (:data @a))}})
(swap! counter + 2)
(recur a))
(defn print-loop [sec]
(println "date: " (.toString (java.util.Date.)))
(println "memory: " (/ (:resident (sig/ps-memory)) 1000000.) "MB")
(println "counter: " @counter)
(println "")
(println "")
(Thread/sleep (* 1000 sec))
(recur sec))
(def loop1 (future (update-loop1 data)))
(def loop2 (future (update-loop1 data)))
(def loop-pr (future (print-loop 60)))
update-in
循环的结果:date: Tue Oct 09 21:13:06 EST 2012 memory: 152.072192 MB counter: 0 date: Tue Oct 09 21:15:06 EST 2012 memory: 157.904896 MB counter: 53109426 date: Tue Oct 09 21:18:06 EST 2012 memory: 158.007296 MB counter: 134171090 date: Tue Oct 09 21:21:06 EST 2012 memory: 157.896704 MB counter: 214766350 date: Tue Oct 09 21:23:06 EST 2012 memory: 158.011392 MB counter: 268002504
正如你所看到的,gc确实起步了,但数据结构肯定在增长。
date: Tue Oct 09 21:25:01 EST 2012 memory: 157.667328 MB counter: 0 date: Tue Oct 09 21:26:01 EST 2012 memory: 158.86336 MB counter: 215137676 date: Tue Oct 09 21:27:01 EST 2012 memory: 150.474752 MB counter: 428276080 date: Tue Oct 09 21:30:02 EST 2012 memory: 150.478848 MB counter: 1052419088 date: Tue Oct 09 21:33:02 EST 2012 memory: 150.663168 MB counter: 1697444032 date: Tue Oct 09 21:36:02 EST 2012 memory: 150.77376 MB counter: 2360045388
复位!速度较慢但内存较少。