in reply to Re: Eek! goto?
in thread Eek! goto?

It's a good point given the example code. In the actual application, the case cannot arise as lengths of 12 or greater are reduced to <12 by a preceding loop that process the input 12-bytes at a time. Zero length strings are rejected on entry and length can't return negatives.

This peice of code is designed to deal with the "left-overs" (length%12).


Examine what is said, not who speaks.

The 7th Rule of perl club is -- pearl clubs are easily damaged. Use a diamond club instead.

Replies are listed 'Best First'.
Re: Eek! goto?
by Abigail-II (Bishop) on Feb 12, 2003 at 13:25 UTC
    Oh, so it does look like you need Duff's device.... ;-)

    Abigail

      If it were not for pfaut's unpack suggestion, I almsot certainly would be using it, but the loss of performance of the perl implimentation relative to the C switch version means pushing as much of the work into perl as I can has dividends.

      The original C code is here.

      My current best perl implementation of the while thing is the hash2() in the test code below. hash() being my original brute force conversion. The two version appear to function the same as each other, with the unpack version coming out about %50 faster.

      However, the number of first pass collisions worries me a little. It could be just be a function of the limited range of inputs, but its higher than I expected. The other possibility is that both implementations are equally wrong. If you (or anyone) has a few moments to compare the perl and the C versions and point out any obvious differences I'd be grateful.

      Also, if anyone has any idea's or pointers for methods of testing the goodness of this type of hashing function I'd really like to hear/see them. Unfortunately, the vast majority of the hits on google relate to hashing fuctions used for cryptography which is a completly different ballpark. I'm slowly whittling them down and wading through them, but haven't found anything applicable yet.

      My test code

      Benchmark results

      c:\test>hash 456976 values resulted in 233710 unique hashes & a maximum of 34 first + pass collisions 456976 values resulted in 233710 unique hashes & a maximum of 34 first + pass collisions 1 trial of hash (195.751s total) 1 trial of hash2 (133.032s total)

      Examine what is said, not who speaks.

      The 7th Rule of perl club is -- pearl clubs are easily damaged. Use a diamond club instead.

        Since you already have the C code, it shouldn't be too hard to write an Inline::C version. Even if for some reason you don't want to end up with an Inline::C version for production or distribution, you could use the Inline::C function for testing - both the C and the Perl function should return the same values.

        And it would also be interesting to benchmark the two.

        Abigail

        Looks like a typo in hash(). Should the third line inside the while loop be $c = ...?

        --- print map { my ($m)=1<<hex($_)&11?' ':''; $m.=substr('AHJPacehklnorstu',hex($_),1) } split //,'2fde0abe76c36c914586c';