Hi Mark,

I understand the value of, sometimes, comparing raw speed of simple
datastructures operations.
So in your example, if I understand correctly, you're not computing the time
taken to compute the new value to be inserted, but rather just the time of
insertion.

I've seen in the past collegues of mine rejecting web frameworks because
they had this kind of "simple benchmark" approach : the web page to be
served was doing nothing at all (as in "serve a static hello world
message"), and they were comparing plain JSP, Struts, and another framework
whose name I can't recall right now.
Of course, as expected with such a case, JSP was faster than Struts was
faster than the other framework, following the number of indirection levels
each solution was introducing.
What was wrong, was that those raw numbers were irrelevant in 99% of use
cases of web page access, where the time taken to serve a request was
dominated by I/O (database access). And the "wrong" framework (with respect
to this criteria) was chosen.

Ok, I'm pretty sure you know this above story well, I still wanted to talk
about it, just in case.

Now for Clojure and hashmap, I'd like to share some thoughts.
I'm basically segregating "use cases" into two categories :
  a. Feeding the hash map in big chunks : here, we are close to your
example. The values have already been computed and (presumably) stored
somewhere, and we just want to create a hashmap as quickly as possible. In
this scenario, it seems that it's possible to use transients.
  b. Feeding the hash map concurrently : here, in the case where the need
for feeding the hash map concurrently is derived from the need to spread
non-trivial computations over multiple threads, I can see the ratio time to
compute value/time to store value become high, and thus the difference
between insertion times be less relevant.



2010/12/29 Mark Engelberg <mark.engelb...@gmail.com>

> Just for fun, I was curious to see what it would be like,
> performance-wise, to simulate a synchronized mutable hash map by
> putting a clojure hash map inside an atom, and making this accessible
> to Java code via the map interface.
>
> I didn't try to implement the entire map interface, but just the major
> things for testing purposes.  The code is below.
>
> Benchmarking insertions on my machine, I'm seeing that the Clojure
> code (Clojure 1.2, java -server) takes roughly 8-20x longer (depending
> on how large the hashmap is).
>
> To test, for example, I do something like
> (def ^com.justforfun.NonBlockingHashMap h
> (com.justforfun.NonBlockingHashMap.))
> (def ^java.util.Map j (. java.util.Collections synchronizedMap
> (java.util.HashMap.)))
>
> (time (doseq [i (range 100000)] (.put h i 2)))   ;900ms
> (time (doseq [i (range 100000)] (.put j i 2)))    ;70ms
>
> Does this seem reasonable, or is there a better way to do this test?
> Frankly, I was expecting Clojure's numbers to compare a bit more
> favorably.
> If you repeat the run, shoving new values into the existing hash
> table, make sure to change the value you're sticking into the hash
> table (Clojure optimizes when you store the same value in the hash
> table that's already there).
>
> [Code]
>
> (ns com.justforfun.NonBlockingHashMap
>  (:gen-class
>   :implements [java.lang.Iterable]
>   :init init
>   :constructors {[] []}
>   :state state
>   :methods [[get [Object] Object]
>             [put [Object Object] void]
>             [clear [] void]
>             [remove [Object] void]
>             [isEmpty [] boolean]
>             [size [] int]]))
>
> (defn -init []
>  [[] (atom {})])
>
> (defn -clear [this]
>  (reset! (.state this) {}))
>
> (defn -get [this k]
>  (get @(.state this) k nil))
>
> (defn -put [this k v]
>  (swap! (.state this) assoc k v))
>
> (defn -remove [this k]
>  (swap! (.state this) dissoc k))
>
> (defn -isEmpty [this]
>  (zero? (count @(.state this))))
>
> (defn -size [this]
>  (count @(.state this)))
>
> (defn -iterator [this]
>  (.iterator @(.state this)))
>
> --
> 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<clojure%2bunsubscr...@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