| From: | David Geier <geidav(dot)pg(at)gmail(dot)com> |
|---|---|
| To: | Kirill Reshke <reshkekirill(at)gmail(dot)com>, PostgreSQL Hackers <pgsql-hackers(at)lists(dot)postgresql(dot)org> |
| Subject: | Re: GiST intarray build speedup: two-arg fast path |
| Date: | 2026-11-02 20:36:16 |
| Message-ID: | 2e8da9d9-874f-4172-b261-e459a601dcb8@gmail.com |
| Views: | Whole Thread | Raw Message | Download mbox | Resend email |
| Thread: | |
| Lists: | pgsql-hackers |
Hi Kirill,
> While profiling index builds for different AMs, I noticed that GiST
> index for inarray
> speds much time in in g_int_union and qsort inside inner_int_union for
> some of benchmark cases.This simple diff gives 1.2-1.5x speedup:
>
>
> diff --git a/contrib/intarray/_int_gist.c b/contrib/intarray/_int_gist.c
> index 98711ac54e2..966409e9582 100644
> --- a/contrib/intarray/_int_gist.c
> +++ b/contrib/intarray/_int_gist.c
> @@ -130,6 +130,14 @@ g_int_union(PG_FUNCTION_ARGS)
> ArrayType *res;
> int totlen = 0;
>
> + if (entryvec->n == 2)
> + {
> + res = inner_int_union(GETENTRY(entryvec, 0),
> +
> GETENTRY(entryvec, 1));
> + *size = VARSIZE(res);
> + PG_RETURN_POINTER(res);
> + }
> +
> for (i = 0; i < entryvec->n; i++)
> {
> ArrayType *ent = GETENTRY(entryvec, i);
>
> Simple case where this helps (SQL was generated by my fuzzer)
>
> CREATE EXTENSION IF NOT EXISTS intarray;
> CREATE TABLE t AS
> SELECT i id,
> ARRAY(SELECT DISTINCT ((hashint4(i*43+j)::bigint)%10000)::int
> FROM generate_series(1,30) j) a
> FROM generate_series(1,5000) i;
>
> CREATE INDEX ON t USING gist(a gist__int_ops);
>
> index create time 46s->26s.
> I did run some other benchmarks and it didn't show any regressions.
Is this because of the specific data ingested or does that hold for all
ingest patterns? Seems like gistMakeUnionKey() always calls
g_int_union() with just two input arrays. Is this where the speedup
comes from?
> Off-list Andrey x4m proposed to try this for n = 3 4 5 etc, which also
> shows some speedup (i. don't have full bench result yet).
The current complexity of g_int_union() is O(N * log N) where N is the
total number of elements across all K input arrays. Your optimization
seems to be a special case of a min-heap based algorithm for K = 2,
where the general complexity is O(N * log K).
Have you thought about implementing a proper min-heap based algorithm?
That would then naturally also work for K > 2.
--
David Geier
| From | Date | Subject | |
|---|---|---|---|
| Next Message | Prashant Chinnam | 2026-11-02 20:49:34 | Re: [PATCH] pgcrypto: Fix sha-crypt rounds= values that do not fit in int (BUG #19743) |
| Previous Message | David Geier | 2026-11-02 20:18:46 | Re: Assert failure in parallel query due to SubPlan double visit for hash join |