scrolling through an old iPad I reopened [0] thread. It has some
optimizations for tsvectors GiST speedup. Lurking through contrib
modules, I noticed hstore call sites, so I tried to speedup them
alike.

Below, diff replaces a simple bit loop with XOR's bitcount and uses
pg_popcount for calculatiuon a signature (sizebitvec).


--- a/contrib/hstore/hstore_gist.c
+++ b/contrib/hstore/hstore_gist.c
@@ -9,6 +9,7 @@
 #include "catalog/pg_type.h"
 #include "common/int.h"
 #include "hstore.h"
+#include "port/pg_bitutils.h"
 #include "utils/pg_crc.h"

 /* gist_hstore_ops opclass options */
@@ -252,15 +253,7 @@
 static int32
 sizebitvec(BITVECP sign, int siglen)
 {
- int32 size = 0,
- i;
-
- LOOPBYTE(siglen)
- {
- size += SUMBIT(sign);
- sign = (BITVECP) (((char *) sign) + 1);
- }
- return size;
+ return pg_popcount(sign, siglen);
 }

 static int
@@ -269,11 +262,8 @@
  int i,
  dist = 0;

- LOOPBIT(siglen)
- {
- if (GETBIT(a, i) != GETBIT(b, i))
- dist++;
- }
+ LOOPBYTE(siglen)
+ dist += pg_number_of_ones[(unsigned char) (a[i] ^ b[i])];
  return dist;
 }

Note that ltree's sizebitvec optimization already calls pg_popcount,
likewize intarray, pg_trgm, and text search for GiST (tsquery gist
does something different for some reason). Said that, almost all
speedup comes from hemdistsign optimization alone.


On this example
CREATE EXTENSION IF NOT EXISTS hstore;

CREATE TABLE t AS
SELECT hstore(ARRAY['a','b','c','d'],
              ARRAY[i::text, (i*3)::text, (i*7)::text, (i*11)::text]) AS h
FROM generate_series(1,50000) as s(i);

\timing on
CREATE INDEX ON t USING gist (h gist_hstore_ops);

Index creating runtime goes from 1454.871- 1488.210 ms to 274.969  -
295.313 ms (about 6 times faster) (4 runs)



[0] 
https://www.postgresql.org/message-id/CAJ3gD9dXb%3D%2BB2pb%2BU%2BLdX-WuEjU7S53gV-r5jOCrZpLmCaou1w%40mail.gmail.com

-- 
Best regards,
Kirill Reshke


Reply via email to