Retrieving a value from a hashmap goes through the following steps:

1) Compute the hashcode of the supplied key.
2) Navigate through the map's internal tree structure to the bucket that
should contain this hashcode (the complexity of this step depends on the
number of different hashcodes stored in the map, not on the complexity of
the key you're searching for).
3) If that bucket is empty, return the provided "missing" value (default:
nil).
4) If the bucket is not empty, for each item in the bucket (all of them
have the same hashcode):
5) Compare for pointer equality; if equal, return the associated value
6) Compare for true equality; if equal, return the associated value
7) Return the provided "missing" value.

So, yes, if you use complex, deeply nested keys _and_ you retrieve the
associated value through using newly-created, value-equal instances of
those keys, it will be a bit slow because you'll have to recompute the
hashcode of the supplied key each time you build it again, and then you'll
still need to traverse the supplied key and the existing copy in the
hashmap for true equality.

In practice, it will most likely be much faster than the worst case because
you will not rebuild the full key from scratch each time, and Clojure value
equality is aware of structural sharing (i.e. if there is a subtree of the
nested keys you're comparing that is actually equal, Clojure will not need
to traverse that part). Due to the way Clojure works with immutable values,
the most likely scenario is that you will have built that key once, and use
the same key (same object in memory) in the hasmap as in the code that
retrieves it; it's also likely that you will have just that one key for
that hashcode value in the map. In that situation, in order to retrieve the
key you just need one hashcode retrieval (it's been cached on first
computation, when you added the key to the map), then one traversal to the
correct bucket (that's typically a O(log32 N) depth), then one pointer
equality check; all of that will be very fast and independent of the
complexity of the key.

Note that the above assumes your keys are Clojure values; if they are
arbitrary Java objects the equality comparison defaults to Java's .equals
so it may be a bit different; also, most Java objects do not cache their
hashcodes.

On 12 November 2017 at 08:35, Jay Porcasi <jaygporc...@gmail.com> wrote:

> thank you very much for the clarification
> so no magic there :-)
> using big nested structures as keys is gonna slow down things a bit
>
> but how caching can help?
>
> On Friday, November 10, 2017 at 12:29:41 PM UTC+7, tbc++ wrote:
>>
>> Most Clojure collections cache their hashcode, so that improves things
>> quite bit. Also, very large collections are rarely used as *keys* in other
>> maps. Most of the time key collections are one or two values. This means
>> that what we're really talking about is combining the hash values of a few
>> values, and that's pretty fast.
>>
>> So sure, the initial hash of one million symbols inside a vector may take
>> a fair amount of time, but I've never seen that in the wild.
>>
>> Timothy
>>
>>
>> --
> 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