更新原子以最小化内存使用的最佳方法是什么

时间:2012-10-08 07:07:12

标签: clojure

我有一个原子,

(def a (atom {:a <some-value>}))

并且它需要不断更新,从长远来看,最有效的内存是什么??

(swap! a assoc :a <next-value>)

(swap! a (fn [_] {:a <next-value>}))

直观地说,根据我在持久性结构上所听到的谈话,我认为第二种方式会慢一点,但从长远来看会更好......但是想要第二种意见。

2 个答案:

答案 0 :(得分:4)

  1. 第一种形式不起作用。
  2. 内存效率无关紧要:一旦旧值被丢弃,如何获得新值对长期内存使用量没有影响。
  3. 您似乎想要reset!,而不是swap!
  4. 考虑为什么你经常更新一个原子,特别是如果你根本不关心它以前的值。您通常可以使用纯函数方法更轻松地完成类似的操作,或者至少使用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

复位!速度较慢但内存较少。