]> granicus.if.org Git - postgresql/commitdiff
Replace bitwise looping with bytewise looping in hemdistsign and
authorTom Lane <tgl@sss.pgh.pa.us>
Fri, 20 Jan 2006 22:46:16 +0000 (22:46 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Fri, 20 Jan 2006 22:46:16 +0000 (22:46 +0000)
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.

contrib/intarray/_int.h
contrib/intarray/_intbig_gist.c
contrib/ltree/_ltree_gist.c
contrib/ltree/ltree.h
contrib/pg_trgm/trgm.h
contrib/pg_trgm/trgm_gist.c
contrib/tsearch2/gistidx.c
contrib/tsearch2/gistidx.h

index ec09b149733a877fa48bc4f0d5074f64153f0723..af67435309e4184373d67779219186ed033a6f5c 100644 (file)
@@ -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 )
index 0064e450ddb9145241cb46d2284656cfe92d9d15..844236068dbaf23ab67adbdcdd604d83e59e87bd 100644 (file)
@@ -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;
 }
index 44e25fd28f1bec00d312443e789339a089b64df5..b95dc333340a146ff68cb84e243f9f4a3702a90d 100644 (file)
@@ -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;
 }
index 0400db8b7740bed95f1e2e8ee2a705b342f52a68..8f9ba4074ffa212452dbfed42e778f92454e2ddf 100644 (file)
@@ -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))
index 73c4cb6aa6f0323ccc333ae1010ef4b086aaddbd..641ffd52a136531f4d3dcf02dff65f57bc4dda4b 100644 (file)
@@ -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 ) )
index 9f1c20cf047034ca74ea2a4c0324a0726ac4b5ee..e7c21a435b3820a8708817e0b26ecd7e32232f63 100644 (file)
@@ -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;
 }
index a01d06d65e73037a608e733e6461aba731ff067e..6aabae277723185d07bc6e6eb3cdd16ec0aa5577 100644 (file)
@@ -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;
 }
index 3f72252b05f5d03bb5b89e4f62d30c0e7c54f655..142318b8c8f011ea9593544e55258bd7a90d27c8 100644 (file)
@@ -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 )