summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Lane2006-01-20 22:46:16 +0000
committerTom Lane2006-01-20 22:46:16 +0000
commit33feb55c478af5f7a4c61232729c524d69d8d965 (patch)
tree3ef1296a7f7196f0d08d58eba0f3fa92917de21a
parent138fdf32bb306e0783c2d383d552d2dc65cd1f07 (diff)
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.
-rw-r--r--contrib/intarray/_int.h5
-rw-r--r--contrib/intarray/_intbig_gist.c39
-rw-r--r--contrib/ltree/_ltree_gist.c42
-rw-r--r--contrib/ltree/ltree.h8
-rw-r--r--contrib/pg_trgm/trgm.h5
-rw-r--r--contrib/pg_trgm/trgm_gist.c39
-rw-r--r--contrib/tsearch2/gistidx.c40
-rw-r--r--contrib/tsearch2/gistidx.h4
8 files changed, 100 insertions, 82 deletions
diff --git a/contrib/intarray/_int.h b/contrib/intarray/_int.h
index ec09b149733..af67435309e 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<SIGLENBIT;i++) {\
- a;\
- }
-
/* beware of multiple evaluation of arguments to these macros! */
#define GETBYTE(x,i) ( *( (BITVECP)(x) + (int)( (i) / BITS_PER_BYTE ) ) )
#define GETBITBYTE(x,i) ( (*((char*)(x)) >> (i)) & 0x01 )
diff --git a/contrib/intarray/_intbig_gist.c b/contrib/intarray/_intbig_gist.c
index 0064e450ddb..844236068db 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);
@@ -205,8 +214,7 @@ sizebitvec(BITVECP sign)
i;
LOOPBYTE(
- size += SUMBIT(sign);
- sign = (BITVECP) (((char *) sign) + 1);
+ size += number_of_ones[(unsigned char) sign[i]];
);
return size;
}
@@ -215,11 +223,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 44e25fd28f1..b95dc333340 100644
--- a/contrib/ltree/_ltree_gist.c
+++ b/contrib/ltree/_ltree_gist.c
@@ -30,18 +30,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)
{
@@ -207,8 +219,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;
}
@@ -217,11 +228,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 0400db8b774..8f9ba4074ff 100644
--- a/contrib/ltree/ltree.h
+++ b/contrib/ltree/ltree.h
@@ -177,10 +177,6 @@ typedef unsigned char *BITVECP;
for(i=0;i<SIGLEN;i++) {\
a;\
}
-#define LOOPBIT(a) \
- for(i=0;i<SIGLENBIT;i++) {\
- a;\
- }
#define GETBYTE(x,i) ( *( (BITVECP)(x) + (int)( (i) / BITBYTE ) ) )
#define GETBITBYTE(x,i) ( ((unsigned char)(x)) >> i & 0x01 )
@@ -238,10 +234,6 @@ typedef unsigned char ABITVEC[ASIGLEN];
for(i=0;i<ASIGLEN;i++) {\
a;\
}
-#define ALOOPBIT(a) \
- for(i=0;i<ASIGLENBIT;i++) {\
- a;\
- }
#define AHASHVAL(val) (((unsigned int)(val)) % ASIGLENBIT)
#define AHASH(sign, val) SETBIT((sign), AHASHVAL(val))
diff --git a/contrib/pg_trgm/trgm.h b/contrib/pg_trgm/trgm.h
index 73c4cb6aa6f..641ffd52a13 100644
--- a/contrib/pg_trgm/trgm.h
+++ b/contrib/pg_trgm/trgm.h
@@ -55,11 +55,6 @@ typedef char *BITVECP;
a;\
}
-#define LOOPBIT(a) \
- for(i=0;i<SIGLENBIT;i++) {\
- a;\
- }
-
#define GETBYTE(x,i) ( *( (BITVECP)(x) + (int)( (i) / BITBYTE ) ) )
#define GETBITBYTE(x,i) ( ((char)(x)) >> 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 9f1c20cf047..e7c21a435b3 100644
--- a/contrib/pg_trgm/trgm_gist.c
+++ b/contrib/pg_trgm/trgm_gist.c
@@ -36,16 +36,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
@@ -298,8 +307,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;
}
@@ -308,11 +316,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 a01d06d65e7..6aabae27772 100644
--- a/contrib/tsearch2/gistidx.c
+++ b/contrib/tsearch2/gistidx.c
@@ -42,16 +42,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);
@@ -435,8 +445,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;
}
@@ -445,11 +454,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 3f72252b05f..142318b8c8f 100644
--- a/contrib/tsearch2/gistidx.h
+++ b/contrib/tsearch2/gistidx.h
@@ -21,10 +21,6 @@ typedef char *BITVECP;
for(i=0;i<SIGLEN;i++) {\
a;\
}
-#define LOOPBIT(a) \
- for(i=0;i<SIGLENBIT;i++) {\
- a;\
- }
#define GETBYTE(x,i) ( *( (BITVECP)(x) + (int)( (i) / BITS_PER_BYTE ) ) )
#define GETBITBYTE(x,i) ( ((char)(x)) >> (i) & 0x01 )