Kevin Kostlan
Kevin Kostlan

Reputation: 3519

Clojure count resource use

Different infinite loops (at the REPL, clojure 1.7.0):

(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?).

The lower loop also hogs memory, so incessant GC may be the reason for the huge CPU usage. But why would there be such a memory difference in the first place?

Upvotes: 1

Views: 109

Answers (1)

Stefan Kamphausen
Stefan Kamphausen

Reputation: 1665

The function range creates a lazy sequence. Lazy sequences create their elements only on-demand. If the beginning of the lazy seq is tied to some variable (either locally with let or globally with def), the seq will cache all its elements and thus consume memory. This is commonly referred to as "holding onto the head of a sequence".

That's why your second example consumes a lot of memory.

I would expect that an analysis with jvisualvm will show that it is not clojure itself that consumes the CPU cycles but the JVM trying to cope with the increasing memory usage.

Finally, count traverses the whole sequence, thereby realizing all elements. In case of just (range) the sequence would never end, it gets stopped when no more memory is available.

Upvotes: 2

Related Questions