【发布时间】:2021-02-03 23:15:56
【问题描述】:
在尝试对复杂计算进行故障排除时发现了一些奇怪的东西。我遇到了一个奇怪的错误,所以我开始逐步建立计算,并且很早就发现意外实现了一个非常长的序列。我有一个这样的列表组合序列:
(0 1 2 3)
(0 1 2 4)
(0 1 2 5)
for n-choose-k for n = 143 和 k = 4 有点不经意地命名为“combos”。我计划将其作为 seq 进行操作以保持合理的内存消耗,但这失败了:
(def combos (combinations 4 143))
(def semantically-also-combos
(filter nil? (map identity combos)))
;; this prints instantly and uses almost no memory, as expected
(println (first combos)) ; prints (0 1 2 3)
;; this takes minutes and runs the JVM out of memory
;; without printing anything
(println (first semantically-also-combos))
根据type,它们都是clojure.lang.LazySeq,但一个按预期工作,另一个使进程崩溃。为什么要实现整个 seq 只是通过身份函数运行它并检查它是否为 nil?
完整的代码重现
(ns my-project.core
(:gen-class))
;;; Copied from rosetta code
(defn combinations
"If m=1, generate a nested list of numbers [0,n)
If m>1, for each x in [0,n), and for each list in the recursion on [x+1,n), cons the two"
[m n]
(letfn [(comb-aux
[m start]
(if (= 1 m)
(for [x (range start n)]
(list x))
(for [x (range start n)
xs (comb-aux (dec m) (inc x))]
(cons x xs))))]
(comb-aux m 0)))
(println "Generating combinations...")
(def combos (combinations 4 143))
(def should-also-be-combos
(filter nil? (map identity combos)))
(defn -main
"Calculates combos"
[& _args]
(println (type combos))
(println (type should-also-be-combos)))
【问题讨论】:
标签: clojure jvm out-of-memory