3

我有一个原子,

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

并且它需要不断更新,从长远来看,最节省内存的调用是什么......?

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

或者

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

直觉上,根据我听到的关于持久结构的谈话,我认为第二种方式会慢一些,但从长远来看会更好......但想要第二个意见。

4

2 回答 2

4
  1. 第一种形式不起作用。
  2. 内存效率无关紧要:一旦旧值被丢弃,如何获得新值对长期内存使用量没有影响。
  3. 你似乎想要reset!,不是swap!
  4. 考虑一下为什么你要如此频繁地更新一个原子,特别是如果你根本不关心它以前的值。您通常可以使用纯函数方法更轻松地完成类似的事情,或者至少使用swap!考虑旧值的函数。
于 2012-10-08T07:12:56.523 回答
0

遵循 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

重启!速度较慢,但​​占用的内存更少。

于 2012-10-09T10:38:31.067 回答