Beefy Boxes and Bandwidth Generously Provided by pair Networks
Don't ask to ask, just ask
 
PerlMonks  

Re^4: elsif chain vs. dispatch

by Marshall (Prior)
on Apr 27, 2009 at 19:58 UTC ( #760413=note: print w/ replies, xml ) Need Help??


in reply to Re^3: elsif chain vs. dispatch
in thread elsif chain vs. dispatch

I don't know what is new in Perl 5.8.3 regarding new re-sizing algorithms based upon buckets used, but if you are curious as to what is happening, the scalar value of a hash, eg my $x = %hash; returns a string like "(10/1024)" showing number of buckets used/total buckets.

To pre-size a hash or force it get bigger, assign a scalar to keys %hash, eg: keys %hash=8192;.

The Perl hash algorithm is:

/* of course C code */ int i = klen; unsigned int hash =0; char *s = key; while (i--) hash = hash *33 + *s++;
Perl cuts the above value to the hash array size of bits, which in Perl is always a power of 2. As mentioned above, this "(10/1024)" string shows number of "buckets" and total "buckets". There is another value, hxv_keys accessible to the Perl "guts" that contains the total number of hash entries.

If the total number of (typo update:) keysentries exceeds the number of buckets used, Perl will increase the hash size by one more bit and recalculate all hash keys again.

So let's say that we have a hash with 8 buckets and for some reason only one of those buckets is being used. When the ninth one shows up, Perl will see (9>8) and will re-size the hash by adding one more bit to the hash key. In practice, this algorithm appears to work pretty well. I guess there are some improvement in >Perl 5.8.3.

Anyway I often work the hashes with say 100,000 things and haven't seen the need yet to override the Perl hash algorithm.


Comment on Re^4: elsif chain vs. dispatch
Download Code
Re^5: elsif chain vs. dispatch
by ikegami (Pope) on Apr 27, 2009 at 20:34 UTC

    The degenerate case has nothing to do with the ratio of used buckets to the number of total buckets.

    The degenerate case occurs when the number of elements in the hash (0+keys(%hash)) is much greater than the number of buckets in use (0+%hash) because most of keys hash to the same value.

    Locating a key in the degenerate case is a linear search since they're all in the same bucket.

      If you let Perl grow the hash, this super degenerate case will be detected and Perl will add bits to the hash key. The num keys start at 8, then 16,32,64,etc. The 9th entry to same hash value with buckets =8 would re-gen the entire hash. Now, I suppose that some case can be generated where at each bit addition, the same thing not only occurs, but becomes harder for earlier versions of Perl to detect!

      I think my general advice about checking these parms: #buckets used, #total buckets and #total entries is a good one when dealing with very large or performance sensitive hashes.

        The 9th entry to same hash value with buckets =8 would re-gen the entire hash.

        That doesn't prevent the degenerate case since you could end up with 9 entries in the same bucket of a 16 bucket hash after the split.

        But that would mean having N/4 keys hashing to the same bucket isn't detected. Which means the worst case is still Θ(N). In fact, if there's an ε > 0 such that it requires more than εN keys to be hashed to a single bucket before Perl reorders the hash, the worst case look up is still Θ(N).
      Completely correct! Yes this could happen. If it keeps happening, then the 17th entry would cause the hash to be re-sized. Then again on the 33rd entry.

      It sounds like Perl 5.8.3+ has made some improvements! Great!

      For Perl versions less than that and even on Perl 5.8.3, I don't think that a user will know more than #buckets, #buckets used and #total entries (ie, user wouldn't know the max entries into a "bucket"), but given those 3 things, a user can make some judgment call about increasing the hash table size and is able to do so.

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://760413]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others exploiting the Monastery: (8)
As of 2014-08-23 02:51 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The best computer themed movie is:











    Results (171 votes), past polls