Rate u32 u64
u32 54.9/s -- -13%
u64 63.3/s 15% --
####
#!/usr/bin/perl
use strict;
use warnings;
use Digest::JHash;
use Benchmark qw(cmpthese);
my @dat;
for my $i (1..100) {
$dat[$i] = '';
$dat[$i] .= chr(int(rand(256))) for 1..100000;
}
cmpthese (100,
{
u32 => sub {
for (1..100) {
my $h = Digest::JHash::jhash($dat[$_]);
}
},
u64 => sub {
for (1..100) {
my $h = Digest::JHash::jhash_orig($dat[$_]);
}
},
} );
##
##
#define MASK32 0xffffffff
#define MIX(a,b,c) \
{ \
a -= b; a &= MASK32; a -= c; a &= MASK32; a ^= ((c>>13)); \
b -= c; b &= MASK32; b -= a; b &= MASK32; b ^= ((a<<8) & MASK32); \
c -= a; c &= MASK32; c -= b; c &= MASK32; c ^= ((b>>13)); \
a -= b; a &= MASK32; a -= c; a &= MASK32; a ^= ((c>>12)); \
b -= c; b &= MASK32; b -= a; b &= MASK32; b ^= ((a<<16) & MASK32); \
c -= a; c &= MASK32; c -= b; c &= MASK32; c ^= ((b>>5) ); \
a -= b; a &= MASK32; a -= c; a &= MASK32; a ^= ((c>>3) ); \
b -= c; b &= MASK32; b -= a; b &= MASK32; b ^= ((a<<10) & MASK32); \
c -= a; c &= MASK32; c -= b; c &= MASK32; c ^= ((b>>15)); \
}
unsigned long jhash( SV* str )
{
STRLEN rawlen;
char* p;
unsigned long a, b, c, len, length;
/* extract the string data and string length from the perl scalar */
p = (char*)SvPV(str, rawlen);
length = len = (unsigned long)rawlen;
/* Test for undef or null string case and return 0 */
if ( length == 0 ) {
DEBUG && printf( "Recieved a null or undef string!\n" );
return 0;
}
DEBUG && printf( "Received string '%.*s'.\n", (int)len, p );
a = b = 0x9e3779b9; /* golden ratio suggested by Jenkins */
c = 0;
while (len >= 12)
{
a += (p[0] + ((((unsigned long)p[1]) << 8) & MASK32 )
+ ((((unsigned long)p[2]) << 16) & MASK32 )
+ ((((unsigned long)p[3]) << 24) & MASK32 )); a &= MASK32;
b += (p[4] + ((((unsigned long)p[5]) << 8) & MASK32 )
+ ((((unsigned long)p[6]) << 16) & MASK32 )
+ ((((unsigned long)p[7]) << 24) & MASK32 )); b &= MASK32;
c += (p[8] + ((((unsigned long)p[9]) << 8) & MASK32 )
+ ((((unsigned long)p[10])<< 16) & MASK32 )
+ ((((unsigned long)p[11])<< 24) & MASK32 )); c &= MASK32;
MIX(a, b, c);
p += 12;
len -= 12;
}
c += length;
switch(len) {
case 11: c+=(((unsigned int)p[10]<< 24) & MASK32 ); c &= MASK32;
case 10: c+=(((unsigned int)p[9] << 16) & MASK32 ); c &= MASK32;
case 9: c+=(((unsigned int)p[8] << 8) & MASK32 ); c &= MASK32;
case 8: b+=(((unsigned int)p[7] << 24) & MASK32 ); b &= MASK32;
case 7: b+=(((unsigned int)p[6] << 16) & MASK32 ); b &= MASK32;
case 6: b+=(((unsigned int)p[5] << 8) & MASK32 ); b &= MASK32;
case 5: b+= ((unsigned int)p[4]); b &= MASK32;
case 4: a+=(((unsigned int)p[3] << 24) & MASK32 ); a &= MASK32;
case 3: a+=(((unsigned int)p[2] << 16) & MASK32 ); a &= MASK32;
case 2: a+=(((unsigned int)p[1] << 8) & MASK32 ); a &= MASK32;
case 1: a+= ((unsigned int)p[0]); a &= MASK32;
}
MIX(a, b, c);
DEBUG && printf( "Hash value is %d.\n", (int)(c) );
return(c);
}