Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Explanation of "Lose your head" in lazy sequences

Tags:

In Clojure programming language, why this code passes with flying colors?

(let [r (range 1e9)] [(first r) (last r)])

While this one fails:

(let [r (range 1e9)] [(last r) (first r)])

I know it is about "Losing your head" advice but would you please explain it to me? I'm not able to digest it yet.

UPDATE:
It is really hard to pick the correct answer, two answers are amazingly informative.
Note: Code snippets are from "The Joy of Clojure".

like image 606
Chiron Avatar asked Apr 18 '11 03:04

Chiron


1 Answers

To elaborate on dfan and Rafał's answers, I've taken the time to run both expressions with the YourKit profiler.

It's fascinating to see the JVM at work. The first program is so GC-friendly that the JVM really shines at managing its memory.

I drew some charts.

GC friendly: (let [r (range 1e9)] [(first r) (last r)])

enter image description here

This program runs very low on memory; overall, less than 6 megabytes. As stated earlier, it is very GC friendly, it makes a lot of collections, but uses very little CPU for that.

Head holder: (let [r (range 1e9)] [(last r) (first r)])

enter image description here

This one is very memory hungry. It goes up to 300 MB of RAM, but that's not enough and the program does not finish (the JVM dies less than one minute later). The GC takes up to 90% of CPU time, which indicates it desperately tries to free any memory it can, but cannot find any (the objects collected are very little to none).

Edit The second program ran out of memory, which triggered a heap dump. An analysis of this dump shows that 70% of the memory is java.lang.Integer objects, which could not be collected. Here's another screenshot:

enter image description here

like image 183
Leonel Avatar answered Sep 19 '22 19:09

Leonel