Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Head retention in Clojure

Tags:

clojure

Reading paragraph about head retention in "Clojure Programming" (page 98), i couldn't figure out what happens in split-with example. I've tried to experiment with repl but it made me more confused.

(time (let [r (range 1e7) 
            a (take-while #(< % 12) r)
            b (drop-while #(< % 12) r)]
        [(count a) (count b)]))
"Elapsed time: 1910.401711 msecs"
[12 9999988]

(time (let [r (range 1e7) 
            a (take-while #(< % 12) r)
            b (drop-while #(< % 12) r)]
        [(count b) (count a)]))
"Elapsed time: 3580.473787 msecs"
[9999988 12]

(time (let [r (range 1e7) 
            a (take-while #(< % 12) r)
            b (drop-while #(< % 12) r)]
        [(count b)]))
"Elapsed time: 3516.70982 msecs"
[9999988]

As you can see from the last example, if I don't compute a, time consuming somehow grows. I guess, i've missed something here, but what?

like image 549
Nikolay D Khodyunya Avatar asked Nov 08 '12 08:11

Nikolay D Khodyunya


2 Answers

Count is O(1). That's why your measurements don't depend on it.

like image 133
mobyte Avatar answered Oct 15 '22 18:10

mobyte


The count function is O(1) for Counted collections, which includes vectors and lists.

Sequences, on the other hand, are not counted which makes count O(n) for them. The important part here is that the functions take-while and drop-while return sequences. The fact that they are also lazy is not a major factor here.

like image 27
Jeremy Avatar answered Oct 15 '22 18:10

Jeremy