You're right; now that I look more closely, there is a difference between
the two expressions.

The split-with function is literally a combination of take-while and
drop-while, like so:

(defn split-with [pred coll]
  [(take-while pred coll) (drop-while pred coll)])


This is important because it means the same seq is being used in two
separate expressions, t and d. This means the head of the seq is implicitly
retained, because both expressions need to start from the same base.

When you call (count t) first, it iterates through 12 elements, then stops.
This means the range seq has 12 realised values when you evaluate (count d).

On the other hand, when you call (count d) first, it needs to iterate
through all 1e8 elements of the list. This means the range seq is fully
realised when you evaluate (count t).

So one way round realises 12 elements of the seq, the other way realises
all 1e8 elements. That's the difference in memory usage, and probably has
some effect on the time taken as well.

- James


On 12 July 2014 12:15, Cecil Westerhof <cldwester...@gmail.com> wrote:

> 2014-07-12 11:56 GMT+02:00 James Reeves <ja...@booleanknot.com>:
>
> The JVM optimises sections of code that are frequently executed, so the
>> second expression benefits from the optimisation that happens during the
>> first expression. My guess is that if you were to swap the two expressions
>> around, you'd find that the first expression always takes longer, no matter
>> which way around it is.
>>
>> Benchmarking libraries like Criterium get around this by "warming up" the
>> JVM with a few practice runs before recording the benchmarks. I'd advise
>> using Criterium over clojure.core/time if you want to benchmark things
>> accurately.
>>
>
> ​That may be a part of it, but there is more to it. When I use 1e9 for
> range-length I get:
>     OutOfMemoryError GC overhead limit exceeded  java.lang.Long.valueOf
> (Long.java:577)
>     "Elapsed time: 56970.117811 msecs"
>     [999999988 12]
>
> By doing first (count d) and then (count t) something is retained, which
> makes the execution longer and the usage of memory higher. And I do not
> understand that. Because when creating t and d everything has to be
> evaluated​. So why has the sequence of the statements influence on the
> memory usage?
>
>
>
>> On 12 July 2014 10:29, Cecil Westerhof <cldwester...@gmail.com> wrote:
>>
>>> I do the following (with range-length 1e8):
>>>     (time (let [[t d] (split-with #(< % 12) (range range-length))]
>>>                [(count d) (count t)]))
>>>
>>>     (time (let [[t d] (split-with #(< % 12) (range range-length))]
>>>                (into [] (reverse [(count t) (count d)]))))
>>>
>>> ​This gives:
>>>     "Elapsed time: 68105.338314 msecs"
>>>     [99999988 12]
>>>     "Elapsed time: 11545.667394 msecs"
>>>     [99999988 12]
>>>
>>> So the first expression​
>>> ​ takes as six times as long to evaluate. ​
>>> ​I understood that this has to do with that in the first case there is
>>> head retention. But I do not understand this. What is happening here?​
>>>
>>>
> --
> Cecil Westerhof
>
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with
> your first post.
> To unsubscribe from this group, send email to
> clojure+unsubscr...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en
> ---
> You received this message because you are subscribed to the Google Groups
> "Clojure" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to clojure+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
>

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to