On Nov 14, 2010, at 2:16 PM, Eric Kobrin wrote:

> In the API it is suggested to use `seq` to check if coll is empty.

Your timing results raise some interesting questions, however, the API doesn't 
suggest using 'seq' to check if a collection is empty. That's what 'empty?' is 
for. The documentation note suggests (for style purposes apparently) that you 
use 'seq' to test that the collection is not empty. So to be precise you are 
testing two different things below. For instance, (identical? coll []) is true 
when coll is an empty vector. (seq coll) is true when coll is not empty. The 
correct equivalent would be to test (empty? coll).

Of course, this doesn't change the results. I get similar timings with empty?:
user=> (let [iterations 100000000] (time (dotimes [_ iterations]
                                    (identical? [] []))) (time (dotimes [_ 
iterations] (empty? []))))
"Elapsed time: 2.294 msecs"
"Elapsed time: 2191.256 msecs"
nil
user=> (let [iterations 100000000] (time (dotimes [_ iterations]                
                                                                                
                                                                                
                              
                                           (identical? "" ""))) (time (dotimes 
[_ iterations] (empty? ""))))
"Elapsed time: 2.657 msecs"
"Elapsed time: 4654.622 msecs"
nil
user=> (let [iterations 100000000] (time (dotimes [_ iterations]                
                                                                                
                                                                                
                              
                                           (identical? () ()))) (time (dotimes 
[_ iterations] (empty? ()))))
"Elapsed time: 2.608 msecs"
"Elapsed time: 2144.142 msecs"
nil

This isn't so surprising though, considering that 'identical?' is the simplest 
possible test you could try--do two references point to the same object in 
memory? It can't get any more efficient than that.

Have all good days,
David Sletten

> 
> I was working on some code recently found that my biggest performance
> bottleneck was calling `seq` to check for emptiness. The calls to
> `seq` were causing lots of object allocation and taking noticeable CPU
> time. I switched to using `identical?` to explicitly compare against
> the empty vector and was rewarded with a drastic reduction in
> execution time.
> 
> Here are some hasty tests showing just how big the difference can be:
> 
> user=> (let [iterations 100000000] (time (dotimes [_ iterations]
> (identical? [] []))) (time (dotimes [_ iterations] (seq []))))
> "Elapsed time: 3.512 msecs"
> "Elapsed time: 2512.366 msecs"
> nil
> user=> (let [iterations 100000000] (time (dotimes [_ iterations]
> (identical? "" ""))) (time (dotimes [_ iterations] (seq ""))))
> "Elapsed time: 3.898 msecs"
> "Elapsed time: 5607.865 msecs"
> nil
> user=> (let [iterations 100000000] (time (dotimes [_ iterations]
> (identical? () ()))) (time (dotimes [_ iterations] (seq ()))))
> "Elapsed time: 3.768 msecs"
> "Elapsed time: 2258.095 msecs"
> nil
> 
> Has any thought been given to providing a faster `empty?` that is not
> based on seq?
> 
> Thanks,
> Eric Kobrin
> 
> -- 
> 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 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

Reply via email to