2016-07-14 50 views
1

不同的无限循环(在REPL,Clojure的1.7.0):Clojure的计数资源利用

(count (range)) ; ~100% of 1 CPU, as expected. 
(def x (range)) 
(count x) ; Over 7 CPUs maxed out, on a 4-core machine (hyper threading?). 

较低的循环还猪的内存,所以不断的GC可能是巨大的CPU占用率的原因。但为什么首先会有这样的记忆差异?

+3

'count'在计数时不保留数据。但是通过'def',物化数据被'x'变量保留。 – zerkms

回答

2

功能range创建一个惰性序列。懒序列仅按需创建元素。如果懒惰seq的开始被绑定到某个变量(本地使用let或全局使用def),则seq将缓存其所有元素并因此消耗内存。这通常被称为“保持序列的头部”。

这就是为什么你的第二个例子消耗大量内存。

我期望用jvisualvm进行分析可以发现,clojure本身并不消耗CPU周期,而是尝试应对不断增加的内存使用量的JVM。

最后,count遍历整个序列,从而实现所有元素。在仅仅(range)的情况下,该序列永远不会结束,当没有更多存储器可用时它会停止。

+0

他们为什么要缓存?它是用于记忆表演吗? –

+0

@KevinKostlan因为一个序列可能会产生一个包含当前时间的元素。这意味着如果你不存储物化数据,那么在同一个*序列上的第二次迭代将产生不同的结果。 – zerkms