4

我正在尝试生成一个序列,该序列对应于对非常宽、深的树的广度优先搜索……当我沿着​​序列走得太远时,我遇到了内存问题。在 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 堆空间”。我在 Macbook Air 上从 Eclipse/CounterClockwise 中的 REPL 运行它们。

我对 Clojure 还是很陌生,所以在为此苦苦挣扎了一天之后,我希望这是我忽略的微不足道的事情。我意识到我可以增加堆大小以降低问题发生的可能性,但是我最终想要处理的序列非常庞大,我认为这对我没有帮助。

我尝试用“drop”替换“take”(在上面的示例中),以避免保持头部 - 这没有区别。

4

1 回答 1

2

我错过了多伦。问题似乎出在 StringBuilder str 上。

如果我按以下方式替换 get-children,则此方法有效:

 (defn get-children [n] (map #(if (seq? n) (conj n %) (conj (list n) %)) atoms))
于 2012-06-08T16:23:43.593 回答