From: Tom Lane Date: Fri, 20 Jan 2006 22:46:40 +0000 (+0000) Subject: Replace bitwise looping with bytewise looping in hemdistsign and X-Git-Tag: REL8_1_3~34 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=4977c2b31b26f5a738f5f85dd03c5275ad3ce058;p=postgresql Replace bitwise looping with bytewise looping in hemdistsign and sizebitvec of tsearch2, as well as identical code in several other contrib modules. This provided about a 20X speedup in building a large tsearch2 index ... didn't try to measure its effects for other operations. Thanks to Stephan Vollmer for providing a test case. --- diff --git a/contrib/intarray/_int.h b/contrib/intarray/_int.h index 2231bdb095..f89f276882 100644 --- a/contrib/intarray/_int.h +++ b/contrib/intarray/_int.h @@ -68,11 +68,6 @@ typedef char *BITVECP; a;\ } -#define LOOPBIT(a) \ - for(i=0;i> (i)) & 0x01 ) diff --git a/contrib/intarray/_intbig_gist.c b/contrib/intarray/_intbig_gist.c index 237281aec5..c49a2aab53 100644 --- a/contrib/intarray/_intbig_gist.c +++ b/contrib/intarray/_intbig_gist.c @@ -20,16 +20,25 @@ Datum g_intbig_picksplit(PG_FUNCTION_ARGS); Datum g_intbig_union(PG_FUNCTION_ARGS); Datum g_intbig_same(PG_FUNCTION_ARGS); -#define SUMBIT(val) ( \ - GETBITBYTE((val),0) + \ - GETBITBYTE((val),1) + \ - GETBITBYTE((val),2) + \ - GETBITBYTE((val),3) + \ - GETBITBYTE((val),4) + \ - GETBITBYTE((val),5) + \ - GETBITBYTE((val),6) + \ - GETBITBYTE((val),7) \ -) +/* Number of one-bits in an unsigned byte */ +static const uint8 number_of_ones[256] = { + 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, + 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, + 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, + 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, + 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, + 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8 +}; PG_FUNCTION_INFO_V1(_intbig_in); Datum _intbig_in(PG_FUNCTION_ARGS); @@ -194,8 +203,7 @@ sizebitvec(BITVECP sign) i; LOOPBYTE( - size += SUMBIT(sign); - sign = (BITVECP) (((char *) sign) + 1); + size += number_of_ones[(unsigned char) sign[i]]; ); return size; } @@ -204,11 +212,12 @@ static int hemdistsign(BITVECP a, BITVECP b) { int i, + diff, dist = 0; - LOOPBIT( - if (GETBIT(a, i) != GETBIT(b, i)) - dist++; + LOOPBYTE( + diff = (unsigned char) (a[i] ^ b[i]); + dist += number_of_ones[diff]; ); return dist; } diff --git a/contrib/ltree/_ltree_gist.c b/contrib/ltree/_ltree_gist.c index c2b9af9770..f014b62a21 100644 --- a/contrib/ltree/_ltree_gist.c +++ b/contrib/ltree/_ltree_gist.c @@ -31,18 +31,30 @@ Datum _ltree_consistent(PG_FUNCTION_ARGS); #define GETENTRY(vec,pos) ((ltree_gist *) DatumGetPointer((vec)->vector[(pos)].key)) #define NEXTVAL(x) ( (ltree*)( (char*)(x) + INTALIGN( VARSIZE(x) ) ) ) -#define SUMBIT(val) ( \ - GETBITBYTE(val,0) + \ - GETBITBYTE(val,1) + \ - GETBITBYTE(val,2) + \ - GETBITBYTE(val,3) + \ - GETBITBYTE(val,4) + \ - GETBITBYTE(val,5) + \ - GETBITBYTE(val,6) + \ - GETBITBYTE(val,7) \ -) + +/* Number of one-bits in an unsigned byte */ +static const uint8 number_of_ones[256] = { + 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, + 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, + 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, + 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, + 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, + 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8 +}; + #define WISH_F(a,b,c) (double)( -(double)(((a)-(b))*((a)-(b))*((a)-(b)))*(c) ) + static void hashing(BITVECP sign, ltree * t) { @@ -204,8 +216,7 @@ sizebitvec(BITVECP sign) i; ALOOPBYTE( - size += SUMBIT(*(char *) sign); - sign = (BITVECP) (((char *) sign) + 1); + size += number_of_ones[(unsigned char) sign[i]]; ); return size; } @@ -214,11 +225,12 @@ static int hemdistsign(BITVECP a, BITVECP b) { int i, + diff, dist = 0; - ALOOPBIT( - if (GETBIT(a, i) != GETBIT(b, i)) - dist++; + ALOOPBYTE( + diff = (unsigned char) (a[i] ^ b[i]); + dist += number_of_ones[diff]; ); return dist; } diff --git a/contrib/ltree/ltree.h b/contrib/ltree/ltree.h index 0400db8b77..8f9ba4074f 100644 --- a/contrib/ltree/ltree.h +++ b/contrib/ltree/ltree.h @@ -177,10 +177,6 @@ typedef unsigned char *BITVECP; for(i=0;i> i & 0x01 ) @@ -238,10 +234,6 @@ typedef unsigned char ABITVEC[ASIGLEN]; for(i=0;i> i & 0x01 ) #define CLRBIT(x,i) GETBYTE(x,i) &= ~( 0x01 << ( (i) % BITBYTE ) ) diff --git a/contrib/pg_trgm/trgm_gist.c b/contrib/pg_trgm/trgm_gist.c index 33ed6d5e1f..f8f61e108a 100644 --- a/contrib/pg_trgm/trgm_gist.c +++ b/contrib/pg_trgm/trgm_gist.c @@ -39,16 +39,25 @@ Datum gtrgm_picksplit(PG_FUNCTION_ARGS); #define GETENTRY(vec,pos) ((TRGM *) DatumGetPointer((vec)->vector[(pos)].key)) -#define SUMBIT(val) ( \ - GETBITBYTE(val,0) + \ - GETBITBYTE(val,1) + \ - GETBITBYTE(val,2) + \ - GETBITBYTE(val,3) + \ - GETBITBYTE(val,4) + \ - GETBITBYTE(val,5) + \ - GETBITBYTE(val,6) + \ - GETBITBYTE(val,7) \ -) +/* Number of one-bits in an unsigned byte */ +static const uint8 number_of_ones[256] = { + 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, + 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, + 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, + 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, + 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, + 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8 +}; Datum @@ -301,8 +310,7 @@ sizebitvec(BITVECP sign) i; LOOPBYTE( - size += SUMBIT(*(char *) sign); - sign = (BITVECP) (((char *) sign) + 1); + size += number_of_ones[(unsigned char) sign[i]]; ); return size; } @@ -311,11 +319,12 @@ static int hemdistsign(BITVECP a, BITVECP b) { int i, + diff, dist = 0; - LOOPBIT( - if (GETBIT(a, i) != GETBIT(b, i)) - dist++; + LOOPBYTE( + diff = (unsigned char) (a[i] ^ b[i]); + dist += number_of_ones[diff]; ); return dist; } diff --git a/contrib/tsearch2/gistidx.c b/contrib/tsearch2/gistidx.c index c0d15de691..3f5a6bffaa 100644 --- a/contrib/tsearch2/gistidx.c +++ b/contrib/tsearch2/gistidx.c @@ -43,16 +43,26 @@ PG_FUNCTION_INFO_V1(gtsvector_picksplit); Datum gtsvector_picksplit(PG_FUNCTION_ARGS); #define GETENTRY(vec,pos) ((GISTTYPE *) DatumGetPointer((vec)->vector[(pos)].key)) -#define SUMBIT(val) ( \ - GETBITBYTE(val,0) + \ - GETBITBYTE(val,1) + \ - GETBITBYTE(val,2) + \ - GETBITBYTE(val,3) + \ - GETBITBYTE(val,4) + \ - GETBITBYTE(val,5) + \ - GETBITBYTE(val,6) + \ - GETBITBYTE(val,7) \ -) + +/* Number of one-bits in an unsigned byte */ +static const uint8 number_of_ones[256] = { + 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, + 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, + 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, + 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, + 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, + 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8 +}; static int4 sizebitvec(BITVECP sign); @@ -436,8 +446,7 @@ sizebitvec(BITVECP sign) i; LOOPBYTE( - size += SUMBIT(*(char *) sign); - sign = (BITVECP) (((char *) sign) + 1); + size += number_of_ones[(unsigned char) sign[i]]; ); return size; } @@ -446,11 +455,12 @@ static int hemdistsign(BITVECP a, BITVECP b) { int i, + diff, dist = 0; - LOOPBIT( - if (GETBIT(a, i) != GETBIT(b, i)) - dist++; + LOOPBYTE( + diff = (unsigned char) (a[i] ^ b[i]); + dist += number_of_ones[diff]; ); return dist; } diff --git a/contrib/tsearch2/gistidx.h b/contrib/tsearch2/gistidx.h index 7e243534fb..dd9b99cf05 100644 --- a/contrib/tsearch2/gistidx.h +++ b/contrib/tsearch2/gistidx.h @@ -22,10 +22,6 @@ typedef char *BITVECP; for(i=0;i> (i) & 0x01 )