[sldev] LLUUIDHashMap vs hash_map

Douglas Soo doug at lindenlab.com
Thu Sep 20 07:31:29 PDT 2007


The LLUUIDHashMap is an EXTREMELY specialized hash map that was primarily 
designed for extremely fast lookup and iteration over a map of objects 
keyed by UUIDs - specifically for the simulator, which spends a lot of its 
time iterating over lists of this type (looking up and iterating through 
objects and scripts on the simulator).

Unless you are iterating or looking through objects EXTREMELY often (enough 
to show up as more than a couple percent of time in a time-based profile), 
I would stay far away from it.  It doesn't use any of the standard STL 
semantics for iteration, and is assuredly not thread-safe, or anything else 
that you'd really like.  In fact, unless there are performance or memory 
utilization reasons, I would convert the existing code away from using it.

Also, hash_map isn't part of the official STL standard, so even though it's 
in common usage, I would stay away from it for portability reasons.  So, I 
would stick with a standard map unless you really need to iterate or look 
things up extremely frequently (> 10000 times/frame).

More about LLUUIDHashMap (for the interested):

The biggest performance bottleneck (by far) on most modern hardware is 
memory access - so all of the weird implementation of the LLUUIDHashMap is 
an attempt by me to reduce the number of times you have to do pointer 
dereferences, and reduce the resulting cache misses.  It's also pretty much 
entirely optimized to work with the number of objects/scripts that you 
typically see on a region, so it's tuned to work well for on the order of 
10s of thousands of elements - it will typically reduce the number of 
pointer dereferences to only 2 or 3 to get an item in the hash.  It also 
takes advantage of the essentially randomized bits in the UUID to reduce 
the amount of work being done to hash the elements.

It's an interesting exercise in profiling to optimize something like this - 
this is where timing-based profilers make a HUGE difference.  There was 
extensive profiling done against this implementation to optimize it.

When running synthetic benchmarks against std::map, it was substantially 
(at least 50%?) faster for both random lookups and iteration.  It was also 
being timed against our legacy containers (LLSkipMap), which were even 
slower at the time (and buggier).  We didn't look at hash_map for the 
aforementioned compatibility reasons.  That being said, this was written to 
improve the performance of some very specific inner loops on the simulator 
code.  If I remember correctly, we probably got around a 10% improvement in 
overall simulator performance by switching to this from the previous 
implementation.

- Doug

--On Thursday, September 20, 2007 2:52 PM +0200 Dale Glass 
<dale at daleglass.net> wrote:

> On Thu, Sep 20, 2007 at 01:20:48PM +0200, Dale Glass wrote:
>> I'm looking at implementing a cache storing data by LLUUID and found the
>> LLUUIDHashMap. I see it seems to be used only in LLMotionRegistry.
>>
>> Should I use it? How about making a hash function for LLUUID and using
>> that instead? I presume that simply using the first/last
>> sizeof(size_t)*8 bits of the LLUUID would work fine.
>
> Been looking a bit more at the source of LLUUIDHashMap, it's weird.
>
> It's hardcoded to 256 buckets, not even as a constant but as a magic
> number in the source (ick!)
>
> It uses an U8 for the hash key, so it can't go higher anyway.
>
> LLUUIDHashNode stores a number of elements that varies depending on the
> argument to the template (why?)
>
>
> So I'm thinking a hash_map could be better for my purposes, as I might
> want more than 256 elements (cache will probably be quite big).
>
> For the hash function I'm considering this:
>
> size_t operator()(const LLUUID&x)
> {
> 	return (size_t)x.getCRC32();
> }
>
>



--
Douglas Soo
Studio Director
Linden Lab


More information about the SLDev mailing list