Commit 33feb55c authored by Tom Lane's avatar Tom Lane

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.
parent 138fdf32
...@@ -68,11 +68,6 @@ typedef char *BITVECP; ...@@ -68,11 +68,6 @@ typedef char *BITVECP;
a;\ a;\
} }
#define LOOPBIT(a) \
for(i=0;i<SIGLENBIT;i++) {\
a;\
}
/* beware of multiple evaluation of arguments to these macros! */ /* beware of multiple evaluation of arguments to these macros! */
#define GETBYTE(x,i) ( *( (BITVECP)(x) + (int)( (i) / BITS_PER_BYTE ) ) ) #define GETBYTE(x,i) ( *( (BITVECP)(x) + (int)( (i) / BITS_PER_BYTE ) ) )
#define GETBITBYTE(x,i) ( (*((char*)(x)) >> (i)) & 0x01 ) #define GETBITBYTE(x,i) ( (*((char*)(x)) >> (i)) & 0x01 )
......
...@@ -20,16 +20,25 @@ Datum g_intbig_picksplit(PG_FUNCTION_ARGS); ...@@ -20,16 +20,25 @@ Datum g_intbig_picksplit(PG_FUNCTION_ARGS);
Datum g_intbig_union(PG_FUNCTION_ARGS); Datum g_intbig_union(PG_FUNCTION_ARGS);
Datum g_intbig_same(PG_FUNCTION_ARGS); Datum g_intbig_same(PG_FUNCTION_ARGS);
#define SUMBIT(val) ( \ /* Number of one-bits in an unsigned byte */
GETBITBYTE((val),0) + \ static const uint8 number_of_ones[256] = {
GETBITBYTE((val),1) + \ 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4,
GETBITBYTE((val),2) + \ 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
GETBITBYTE((val),3) + \ 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
GETBITBYTE((val),4) + \ 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
GETBITBYTE((val),5) + \ 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
GETBITBYTE((val),6) + \ 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
GETBITBYTE((val),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,
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); PG_FUNCTION_INFO_V1(_intbig_in);
Datum _intbig_in(PG_FUNCTION_ARGS); Datum _intbig_in(PG_FUNCTION_ARGS);
...@@ -205,8 +214,7 @@ sizebitvec(BITVECP sign) ...@@ -205,8 +214,7 @@ sizebitvec(BITVECP sign)
i; i;
LOOPBYTE( LOOPBYTE(
size += SUMBIT(sign); size += number_of_ones[(unsigned char) sign[i]];
sign = (BITVECP) (((char *) sign) + 1);
); );
return size; return size;
} }
...@@ -215,11 +223,12 @@ static int ...@@ -215,11 +223,12 @@ static int
hemdistsign(BITVECP a, BITVECP b) hemdistsign(BITVECP a, BITVECP b)
{ {
int i, int i,
diff,
dist = 0; dist = 0;
LOOPBIT( LOOPBYTE(
if (GETBIT(a, i) != GETBIT(b, i)) diff = (unsigned char) (a[i] ^ b[i]);
dist++; dist += number_of_ones[diff];
); );
return dist; return dist;
} }
......
...@@ -30,18 +30,30 @@ Datum _ltree_consistent(PG_FUNCTION_ARGS); ...@@ -30,18 +30,30 @@ Datum _ltree_consistent(PG_FUNCTION_ARGS);
#define GETENTRY(vec,pos) ((ltree_gist *) DatumGetPointer((vec)->vector[(pos)].key)) #define GETENTRY(vec,pos) ((ltree_gist *) DatumGetPointer((vec)->vector[(pos)].key))
#define NEXTVAL(x) ( (ltree*)( (char*)(x) + INTALIGN( VARSIZE(x) ) ) ) #define NEXTVAL(x) ( (ltree*)( (char*)(x) + INTALIGN( VARSIZE(x) ) ) )
#define SUMBIT(val) ( \
GETBITBYTE(val,0) + \ /* Number of one-bits in an unsigned byte */
GETBITBYTE(val,1) + \ static const uint8 number_of_ones[256] = {
GETBITBYTE(val,2) + \ 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4,
GETBITBYTE(val,3) + \ 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
GETBITBYTE(val,4) + \ 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
GETBITBYTE(val,5) + \ 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
GETBITBYTE(val,6) + \ 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
GETBITBYTE(val,7) \ 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) ) #define WISH_F(a,b,c) (double)( -(double)(((a)-(b))*((a)-(b))*((a)-(b)))*(c) )
static void static void
hashing(BITVECP sign, ltree * t) hashing(BITVECP sign, ltree * t)
{ {
...@@ -207,8 +219,7 @@ sizebitvec(BITVECP sign) ...@@ -207,8 +219,7 @@ sizebitvec(BITVECP sign)
i; i;
ALOOPBYTE( ALOOPBYTE(
size += SUMBIT(*(char *) sign); size += number_of_ones[(unsigned char) sign[i]];
sign = (BITVECP) (((char *) sign) + 1);
); );
return size; return size;
} }
...@@ -217,11 +228,12 @@ static int ...@@ -217,11 +228,12 @@ static int
hemdistsign(BITVECP a, BITVECP b) hemdistsign(BITVECP a, BITVECP b)
{ {
int i, int i,
diff,
dist = 0; dist = 0;
ALOOPBIT( ALOOPBYTE(
if (GETBIT(a, i) != GETBIT(b, i)) diff = (unsigned char) (a[i] ^ b[i]);
dist++; dist += number_of_ones[diff];
); );
return dist; return dist;
} }
......
...@@ -177,10 +177,6 @@ typedef unsigned char *BITVECP; ...@@ -177,10 +177,6 @@ typedef unsigned char *BITVECP;
for(i=0;i<SIGLEN;i++) {\ for(i=0;i<SIGLEN;i++) {\
a;\ a;\
} }
#define LOOPBIT(a) \
for(i=0;i<SIGLENBIT;i++) {\
a;\
}
#define GETBYTE(x,i) ( *( (BITVECP)(x) + (int)( (i) / BITBYTE ) ) ) #define GETBYTE(x,i) ( *( (BITVECP)(x) + (int)( (i) / BITBYTE ) ) )
#define GETBITBYTE(x,i) ( ((unsigned char)(x)) >> i & 0x01 ) #define GETBITBYTE(x,i) ( ((unsigned char)(x)) >> i & 0x01 )
...@@ -238,10 +234,6 @@ typedef unsigned char ABITVEC[ASIGLEN]; ...@@ -238,10 +234,6 @@ typedef unsigned char ABITVEC[ASIGLEN];
for(i=0;i<ASIGLEN;i++) {\ for(i=0;i<ASIGLEN;i++) {\
a;\ a;\
} }
#define ALOOPBIT(a) \
for(i=0;i<ASIGLENBIT;i++) {\
a;\
}
#define AHASHVAL(val) (((unsigned int)(val)) % ASIGLENBIT) #define AHASHVAL(val) (((unsigned int)(val)) % ASIGLENBIT)
#define AHASH(sign, val) SETBIT((sign), AHASHVAL(val)) #define AHASH(sign, val) SETBIT((sign), AHASHVAL(val))
......
...@@ -55,11 +55,6 @@ typedef char *BITVECP; ...@@ -55,11 +55,6 @@ typedef char *BITVECP;
a;\ a;\
} }
#define LOOPBIT(a) \
for(i=0;i<SIGLENBIT;i++) {\
a;\
}
#define GETBYTE(x,i) ( *( (BITVECP)(x) + (int)( (i) / BITBYTE ) ) ) #define GETBYTE(x,i) ( *( (BITVECP)(x) + (int)( (i) / BITBYTE ) ) )
#define GETBITBYTE(x,i) ( ((char)(x)) >> i & 0x01 ) #define GETBITBYTE(x,i) ( ((char)(x)) >> i & 0x01 )
#define CLRBIT(x,i) GETBYTE(x,i) &= ~( 0x01 << ( (i) % BITBYTE ) ) #define CLRBIT(x,i) GETBYTE(x,i) &= ~( 0x01 << ( (i) % BITBYTE ) )
......
...@@ -36,16 +36,25 @@ Datum gtrgm_picksplit(PG_FUNCTION_ARGS); ...@@ -36,16 +36,25 @@ Datum gtrgm_picksplit(PG_FUNCTION_ARGS);
#define GETENTRY(vec,pos) ((TRGM *) DatumGetPointer((vec)->vector[(pos)].key)) #define GETENTRY(vec,pos) ((TRGM *) DatumGetPointer((vec)->vector[(pos)].key))
#define SUMBIT(val) ( \ /* Number of one-bits in an unsigned byte */
GETBITBYTE(val,0) + \ static const uint8 number_of_ones[256] = {
GETBITBYTE(val,1) + \ 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4,
GETBITBYTE(val,2) + \ 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
GETBITBYTE(val,3) + \ 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
GETBITBYTE(val,4) + \ 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
GETBITBYTE(val,5) + \ 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
GETBITBYTE(val,6) + \ 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
GETBITBYTE(val,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,
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 Datum
...@@ -298,8 +307,7 @@ sizebitvec(BITVECP sign) ...@@ -298,8 +307,7 @@ sizebitvec(BITVECP sign)
i; i;
LOOPBYTE( LOOPBYTE(
size += SUMBIT(*(char *) sign); size += number_of_ones[(unsigned char) sign[i]];
sign = (BITVECP) (((char *) sign) + 1);
); );
return size; return size;
} }
...@@ -308,11 +316,12 @@ static int ...@@ -308,11 +316,12 @@ static int
hemdistsign(BITVECP a, BITVECP b) hemdistsign(BITVECP a, BITVECP b)
{ {
int i, int i,
diff,
dist = 0; dist = 0;
LOOPBIT( LOOPBYTE(
if (GETBIT(a, i) != GETBIT(b, i)) diff = (unsigned char) (a[i] ^ b[i]);
dist++; dist += number_of_ones[diff];
); );
return dist; return dist;
} }
......
...@@ -42,16 +42,26 @@ PG_FUNCTION_INFO_V1(gtsvector_picksplit); ...@@ -42,16 +42,26 @@ PG_FUNCTION_INFO_V1(gtsvector_picksplit);
Datum gtsvector_picksplit(PG_FUNCTION_ARGS); Datum gtsvector_picksplit(PG_FUNCTION_ARGS);
#define GETENTRY(vec,pos) ((GISTTYPE *) DatumGetPointer((vec)->vector[(pos)].key)) #define GETENTRY(vec,pos) ((GISTTYPE *) DatumGetPointer((vec)->vector[(pos)].key))
#define SUMBIT(val) ( \
GETBITBYTE(val,0) + \ /* Number of one-bits in an unsigned byte */
GETBITBYTE(val,1) + \ static const uint8 number_of_ones[256] = {
GETBITBYTE(val,2) + \ 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4,
GETBITBYTE(val,3) + \ 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
GETBITBYTE(val,4) + \ 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
GETBITBYTE(val,5) + \ 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
GETBITBYTE(val,6) + \ 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
GETBITBYTE(val,7) \ 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); static int4 sizebitvec(BITVECP sign);
...@@ -435,8 +445,7 @@ sizebitvec(BITVECP sign) ...@@ -435,8 +445,7 @@ sizebitvec(BITVECP sign)
i; i;
LOOPBYTE( LOOPBYTE(
size += SUMBIT(*(char *) sign); size += number_of_ones[(unsigned char) sign[i]];
sign = (BITVECP) (((char *) sign) + 1);
); );
return size; return size;
} }
...@@ -445,11 +454,12 @@ static int ...@@ -445,11 +454,12 @@ static int
hemdistsign(BITVECP a, BITVECP b) hemdistsign(BITVECP a, BITVECP b)
{ {
int i, int i,
diff,
dist = 0; dist = 0;
LOOPBIT( LOOPBYTE(
if (GETBIT(a, i) != GETBIT(b, i)) diff = (unsigned char) (a[i] ^ b[i]);
dist++; dist += number_of_ones[diff];
); );
return dist; return dist;
} }
......
...@@ -21,10 +21,6 @@ typedef char *BITVECP; ...@@ -21,10 +21,6 @@ typedef char *BITVECP;
for(i=0;i<SIGLEN;i++) {\ for(i=0;i<SIGLEN;i++) {\
a;\ a;\
} }
#define LOOPBIT(a) \
for(i=0;i<SIGLENBIT;i++) {\
a;\
}
#define GETBYTE(x,i) ( *( (BITVECP)(x) + (int)( (i) / BITS_PER_BYTE ) ) ) #define GETBYTE(x,i) ( *( (BITVECP)(x) + (int)( (i) / BITS_PER_BYTE ) ) )
#define GETBITBYTE(x,i) ( ((char)(x)) >> (i) & 0x01 ) #define GETBITBYTE(x,i) ( ((char)(x)) >> (i) & 0x01 )
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment