Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1vdAQ2-00Em0X-2O for pgsql-hackers@arkaria.postgresql.org; Tue, 06 Jan 2026 17:00:32 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.96) (envelope-from ) id 1vdAQ0-009MPy-1y for pgsql-hackers@arkaria.postgresql.org; Tue, 06 Jan 2026 17:00:29 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1vdAQ0-009MPq-0d for pgsql-hackers@lists.postgresql.org; Tue, 06 Jan 2026 17:00:29 +0000 Received: from lahtoruutu.iki.fi ([185.185.170.37]) by magus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1vdAPy-004vi7-13 for pgsql-hackers@postgresql.org; Tue, 06 Jan 2026 17:00:28 +0000 Received: from [10.0.2.15] (unknown [130.41.208.2]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits) key-exchange x25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) (Authenticated sender: hlinnaka) by lahtoruutu.iki.fi (Postfix) with ESMTPSA id 4dly8m0QSTz49Q42; Tue, 06 Jan 2026 19:00:23 +0200 (EET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=iki.fi; s=lahtoruutu; t=1767718824; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=xpVC8fMPdCInUw0J15SdBJ25RlBR/RLa0Vu6zH6MeYU=; b=r5ZE0yzIwC72WA8GtGOgklQ32EdNhjw/bujHVai7E2QWWmo1qna9y9sZpCTvHO3of1wGhy 7DEq5sWnk1gitR2F0G9VJzqqqdTSGBWycOb8sOc6U0UoEn/W0F7Fl9PD8tl96uiCbeiiUq 1hT1jRby1uhCu8uLwflcTDdqWtG/t3Bo/kVK1UlhKhik9rSQQVnK8tBgSsDyTv42s2pNG5 C3tGICcBkWjSqNyDC4WX7M4dLa9frIcuwyuvDKnwDSwGd2bXOR3ucopiuaWAclsS9PAuYc 8oZeQjWIFwQQXn4ZZLlVJ/VU1RoCwIgOZehDnPdB28UvVDewspFGTlJzmSrkGg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=iki.fi; s=lahtoruutu; t=1767718824; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=xpVC8fMPdCInUw0J15SdBJ25RlBR/RLa0Vu6zH6MeYU=; b=Yo7hGXTSq2xco3UTFr/CtUfroODwOOEeR/YgqxBN+VMKdXblpTJeELQGZdMwU8JgTDHlyu FdFgYKtWmB3XFswlUpa+w8Rat3E67hURClExuSCiQXu6YzNxhxkxJ6uUVMcrY28izfhs76 WNfuo/xl9sprpfS+Zcbv6CbCkSZnvlbOc5vfwe/6el8oGnw6B5p3zaFXJOwDctD54TG3YD pb/+Q85rZbOQY/HtRxPraTkOFHb8/BpDUZQmAc9TlXjHLZeYqFrn7YwifIO/corpX6bNbn AzzZiBCYJ8oifskRN9Y9A+vA3fYJmzlUQyxGyWlEqTWKAVoCRV1BREPbXmUrDw== ARC-Authentication-Results: i=1; ORIGINATING; auth=pass smtp.auth=hlinnaka smtp.mailfrom=hlinnaka@iki.fi ARC-Seal: i=1; a=rsa-sha256; d=iki.fi; s=lahtoruutu; cv=none; t=1767718824; b=ey2SkglChf03hhtZgwxiCQYZWjulkOH7YWjxUY58cLrZsMBXqJ0q+/2oZYp8i15yZ+T5g8 Jh46SjJmOUsYq1xCvBCQ43J71k/OUHPulFaKV1xIiAPGECOJhcS37DSHDSLu9KABXOhNKV gEe4v67GXck74aw5z0DuQHI0ZCw81lfpPXrPSoi1lksGtb+vNFVjeAir1mQS4CiK7vLecp tftT4c4s83KnUwVS80GY4/gMIE8wZVLJwcWe1QXjg3QrzcBbUy9rhHlJMG7/RJgx8FQnH3 dFzqILgS1c1usqTaNaY6jhcy8xgQL/IiZYB0GNRrHCumqo5HiK1xY9wvDZShfA== Message-ID: <9ac3931a-180e-4283-a7a8-05eb66099206@iki.fi> Date: Tue, 6 Jan 2026 19:00:23 +0200 MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Subject: Re: Reduce build times of pg_trgm GIN indexes To: David Geier , pgsql-hackers References: <5d366878-2007-4d31-861e-19294b7a583b@gmail.com> Content-Language: en-US From: Heikki Linnakangas In-Reply-To: <5d366878-2007-4d31-861e-19294b7a583b@gmail.com> Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk On 05/01/2026 17:01, David Geier wrote: > The script I used for testing is attached. I ran CREATE INDEX three > times and took the fastest run. I'm getting the following results on my > i9-13950HX dev laptop in release build: > > Data set | Patched (ms) | Master (ms) | Speedup > --------------------|--------------|--------------|---------- > movies(plot) | 3,409 | 10,311 | 3.02x > lineitem(l_comment) | 161,569 | 256,986 | 1.59x > Impressive speedup! > The attached patches do the following: > > - v1-0001-Inline-ginCompareAttEntries.patch: Inline > ginCompareAttEntries() which is very frequently called by the GIN code. Looks good. > - v1-0002-Optimized-comparison-functions.patch: Use FunctionCallInvoke() > instead of FunctionCall2Coll(). This saves a bunch of per-comparison > setup code, such as calling InitFunctionCallInfoData(). You lose the check for NULL result with this. That's probably still worth checking. > - v1-0003-Use-sort_template.h.patch: Use sort_template.h instead of > qsort(), to inline calls to the sort comparator. This is an interim step > that is further improved on by patch 0006. ok > - v1-0004-Avoid-dedup-and-sort-in-ginExtractEntries.patch > ginExtractEntries() deduplicates and sorts the entries returned from the > extract value function. In case of pg_trgm, that is completely redundant > because the trigrams are already deduplicated and sorted. The current > version of this patch is just to demonstrate the potential. We need to > think about what we want here. Ideally, we would require the extraction > function to provide the entries deduplicated and sorted. Alternatively, > we could indicate to ginExtractEntries() if the entries are already > deduplicated and sorted. If we don't want to alter the signature of the > extract value function, we could e.g. use the MSB of the nentries argument. Yeah, this seems wrong as it is. You're assuming that if the extract function returns nullFlags == NULL, the array is already sorted and deduped. > - v1-0005-Make-btint4cmp-branchless.patch: Removes branches from > btint4cmp(), which is heavily called from the GIN code. This might as > well have benefit in other parts of the code base. Seems reasonable. > v1-0006-Use-radix-sort.patch: Replace the sort_template.h-based qsort() > with radix sort. For the purpose of demonstrating the possible gains, > I've only replaced the signed variant for now. I've also tried using > simplehash.h for deduplicating followed by a sort_template.h-based sort. > But that was slower. Ok. > v1-0007-Faster-qunique-comparator.patch: qunique() doesn't require a > full sort comparator (-1 = less, 0 = equal, 1 = greater) but only a > equal/unequal comparator (e.g. 0 = equal and 1 = unequal). The same > optimization can be done in plenty of other places in our code base. > Likely, in most of them the gains are insignificant. Makes sense. I'm a little disappointed the compiler won't do that optimization for us.. Perhaps we should introduce a new qunique_eq() function with a different callback signature: /* like qunique(), but the callback function returns true/false rather than int */ static inline size_t qunique_eq(void *array, size_t elements, size_t width, bool (*equal) (const void *, const void *)) > v1-0008-Add-ASCII-fastpath-to-generate_trgm_only.patch: Typically lots > of text is actually ASCII. Hence, we provide a fast path for this case > which is exercised if the MSB of the current character is unset. This uses pg_ascii_tolower() when for ASCII characters when built with the IGNORECASE. I don't think that's correct, if the proper collation would do something more complicated for than what pg_ascii_tolower() does. Did you measure how big is the impact from each individual patch? Patches 1 and 2 seem pretty much ready to be committed, but I wonder if they make any difference on their own. - Heikki