我正在尝试生成一个序列,该序列对应于一个非常宽的深树的广度优先搜索...当我沿着序列走得太远时,我遇到了记忆问题。在询问IRC频道并查看此处之后,这些问题的第一个原因是无意中抓住了头部;但我看不出我在做什么。
代码非常简单;这是一个显示问题的版本:
(def atoms '(a b c))
(defn get-ch [n] (map #(str n %) atoms))
(defn add-ch
([] (apply concat (iterate add-ch atoms)))
([n] (mapcat get-ch n)))
(dorun (take 20000000 (add-ch)))
这是另一个版本(这是我从#clojure获得帮助之前开始的那个版本),它显示了同样的问题:
(def atoms '(a b c))
(defn get-children [n] (map #(str n %) atoms))
(defn add-layer
([] (add-layer atoms))
([n] (let [child-nodes (mapcat get-children n) ]
(lazy-seq (concat n (add-layer child-nodes))))))
(dorun (take 20000000 (add-layer)))
两者都给我一个“OutOfMemoryError Java堆空间”。我正在使用Eclipse / CounterClockwise中的REPL在Macbook Air上运行它们。
我对Clojure很陌生,所以在对抗这一天之后,我希望这是一件微不足道的事情,我忽视了。我意识到我可以增加堆大小以使问题不太可能发生,但我最终想要处理的序列是如此巨大,我不认为这会对我有所帮助。
我尝试用“drop”替换“take”(在上面的示例中),以避免保持头部 - 这没有任何区别。
答案 0 :(得分:2)
我错过了dorun。 问题似乎与StringBuilder str。
有关如果我将get-children替换为以下内容,则此方法有效:
(defn get-children [n] (map #(if (seq? n) (conj n %) (conj (list n) %)) atoms))