我有一个原子,
(def a (atom {:a <some-value>}))
并且它需要不断更新,从长远来看,最节省内存的调用是什么......?
(swap! a assoc :a <next-value>)
或者
(swap! a (fn [_] {:a <next-value>}))
直觉上,根据我听到的关于持久结构的谈话,我认为第二种方式会慢一些,但从长远来看会更好......但想要第二个意见。
我有一个原子,
(def a (atom {:a <some-value>}))
并且它需要不断更新,从长远来看,最节省内存的调用是什么......?
(swap! a assoc :a <next-value>)
或者
(swap! a (fn [_] {:a <next-value>}))
直觉上,根据我听到的关于持久结构的谈话,我认为第二种方式会慢一些,但从长远来看会更好......但想要第二个意见。
reset!
,不是swap!
。swap!
考虑旧值的函数。遵循 Ankur 的建议以及我的 sigar 分析库包装器的无耻插件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
循环结果:日期:2012 年 10 月 9 日星期二 21:13:06 EST 内存:152.072192 MB 计数器:0 日期:2012 年 10 月 9 日星期二 21:15:06 EST 内存:157.904896 MB 柜台:53109426 日期:2012 年 10 月 9 日星期二 21:18:06 EST 内存:158.007296 MB 柜台:134171090 日期:2012 年 10 月 9 日星期二 21:21:06 EST 内存:157.896704 MB 柜台:214766350 日期:2012 年 10 月 9 日星期二 21:23:06 EST 内存:158.011392 MB 柜台:268002504
如您所见,gc 确实起作用了,但数据结构肯定在增长。
日期:2012 年 10 月 9 日星期二 21:25:01 EST 内存:157.667328 MB 计数器:0 日期:2012 年 10 月 9 日星期二 21:26:01 EST 内存:158.86336 MB 柜台:215137676 日期:2012 年 10 月 9 日星期二 21:27:01 EST 内存:150.474752 MB 柜台:428276080 日期:2012 年 10 月 9 日星期二 21:30:02 EST 内存:150.478848 MB 柜台:1052419088 日期:2012 年 10 月 9 日星期二 21:33:02 EST 内存:150.663168 MB 柜台:1697444032 日期:2012 年 10 月 9 日星期二 21:36:02 EST 内存:150.77376 MB 柜台:2360045388
重启!速度较慢,但占用的内存更少。