Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1lHCWh-0006eU-Fd for pgsql-hackers@arkaria.postgresql.org; Tue, 02 Mar 2021 21:25:55 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.92) (envelope-from ) id 1lHCWe-000073-Es for pgsql-hackers@arkaria.postgresql.org; Tue, 02 Mar 2021 21:25:52 +0000 Received: from makus.postgresql.org ([2001:4800:3e1:1::229]) by malur.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1lHCWe-00006v-86 for pgsql-hackers@lists.postgresql.org; Tue, 02 Mar 2021 21:25:52 +0000 Received: from smtp.outgoing.loopia.se ([93.188.3.37]) by makus.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1lHCWW-0001UW-V2 for pgsql-hackers@postgresql.org; Tue, 02 Mar 2021 21:25:51 +0000 Received: from s807.loopia.se (localhost [127.0.0.1]) by s807.loopia.se (Postfix) with ESMTP id C3A5724628BC for ; Tue, 2 Mar 2021 22:25:40 +0100 (CET) Received: from s630.loopia.se (unknown [172.22.191.5]) by s807.loopia.se (Postfix) with ESMTP id A55132E28F60; Tue, 2 Mar 2021 22:25:40 +0100 (CET) Received: from s472.loopia.se (unknown [172.22.191.5]) by s630.loopia.se (Postfix) with ESMTP id 9A90413AE956; Tue, 2 Mar 2021 22:25:40 +0100 (CET) X-Virus-Scanned: amavisd-new at amavis.loopia.se X-Spam-Flag: NO X-Spam-Score: -1 X-Spam-Level: X-Spam-Status: No, score=-1 tagged_above=-999 required=6.2 tests=[ALL_TRUSTED=-1] autolearn=disabled Received: from s645.loopia.se ([172.22.191.6]) by s472.loopia.se (s472.loopia.se [172.22.190.12]) (amavisd-new, port 10024) with LMTP id 8iGwN6gDhB0l; Tue, 2 Mar 2021 22:25:39 +0100 (CET) X-Loopia-Auth: user X-Loopia-User: daniel@yesql.se X-Loopia-Originating-IP: 89.255.232.193 Received: from [192.168.72.43] (customer-89-255-232-193.stosn.net [89.255.232.193]) (Authenticated sender: daniel@yesql.se) by s645.loopia.se (Postfix) with ESMTPSA id B2E571579F7E; Tue, 2 Mar 2021 22:25:39 +0100 (CET) From: Daniel Gustafsson Message-Id: <0F9ECBA9-1DF2-4C38-BB58-B17EEE6C7B3A@yesql.se> Content-Type: multipart/mixed; boundary="Apple-Mail=_EE7C281A-2743-43FA-A5BE-956125888AA8" Mime-Version: 1.0 (Mac OS X Mail 12.4 \(3445.104.17\)) Subject: Re: A qsort template Date: Tue, 2 Mar 2021 22:25:39 +0100 In-Reply-To: Cc: pgsql-hackers To: Thomas Munro References: X-Mailer: Apple Mail (2.3445.104.17) List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Precedence: bulk --Apple-Mail=_EE7C281A-2743-43FA-A5BE-956125888AA8 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset=us-ascii > On 18 Feb 2021, at 04:09, Thomas Munro wrote: > In another thread[1], I proposed $SUBJECT, but then we found a better > solution to that thread's specific problem. The general idea is still > good though: it's possible to (1) replace several existing copies of > our qsort algorithm with one, and (2) make new specialised versions a > bit more easily than the existing Perl generator allows. So, I'm back > with a rebased stack of patches. I'll leave specific cases for new > worthwhile specialisations for separate proposals; I've heard about > several. Just to play around with this while reviewing I made a qsort_strcmp, = like in the attached, and tested it using a ~9M word [0] randomly shuffled = wordlist. While being too small input to make any meaningful difference in runtime = (it shaved a hair off but it might well be within the error margin) there = was no regression either. More importantly, it was really simple and quick to = make a tailored qsort which is the intention with the patch. While still being = a bit of magic, moving from the Perl generator makes this slightly less magic = IMO so +1 on this approach. A tiny nitpick on the patch itself: + * - ST_COMPARE(a, b) - a simple comparison expression + * - ST_COMPARE(a, b, arg) - variant that takes an extra argument Indentation. All tests pass and the documentation in the the sort_template.h is = enough to go on, but I would prefer to see a comment in port/qsort.c referring back = to sort_template.h for documentation. -- Daniel Gustafsson https://vmware.com/ [0] https://github.com/dwyl/english-words/ shuffled 20 times over --Apple-Mail=_EE7C281A-2743-43FA-A5BE-956125888AA8 Content-Disposition: attachment; filename=qsort_tmpl_strcmp-patch Content-Type: application/octet-stream; x-unix-mode=0644; name="qsort_tmpl_strcmp-patch" Content-Transfer-Encoding: 7bit diff --git a/src/backend/tsearch/ts_utils.c b/src/backend/tsearch/ts_utils.c index ed16a2e25a..920fbaafc4 100644 --- a/src/backend/tsearch/ts_utils.c +++ b/src/backend/tsearch/ts_utils.c @@ -134,7 +134,16 @@ readstoplist(const char *fname, StopList *s, char *(*wordop) (const char *)) /* Sort to allow binary searching */ if (s->stop && s->len > 0) - qsort(s->stop, s->len, sizeof(char *), pg_qsort_strcmp); + qsort_strcmp(s->stop, s->len, sizeof(char *)); +} + +/* + * qsort comparator wrapper for strcmp. + */ +static int +strcmp_cmp(const void *a, const void *b) +{ + return strcmp(*(const char *const *) a, *(const char *const *) b); } bool @@ -142,5 +151,5 @@ searchstoplist(StopList *s, char *key) { return (s->stop && s->len > 0 && bsearch(&key, s->stop, s->len, - sizeof(char *), pg_qsort_strcmp)) ? true : false; + sizeof(char *), strcmp_cmp)) ? true : false; } diff --git a/src/backend/utils/misc/guc-file.l b/src/backend/utils/misc/guc-file.l index 7885a169bb..7f0719b64c 100644 --- a/src/backend/utils/misc/guc-file.l +++ b/src/backend/utils/misc/guc-file.l @@ -1072,7 +1072,7 @@ ParseConfigDirectory(const char *includedir, { int i; - qsort(filenames, num_filenames, sizeof(char *), pg_qsort_strcmp); + qsort_strcmp(filenames, num_filenames, sizeof(char *)); for (i = 0; i < num_filenames; i++) { if (!ParseConfigFile(filenames[i], true, diff --git a/src/include/port.h b/src/include/port.h index 6486db9fdd..441f0c485d 100644 --- a/src/include/port.h +++ b/src/include/port.h @@ -496,9 +496,10 @@ extern int pqGethostbyname(const char *name, struct hostent **result, int *herrno); +/* port/qsort.c */ extern void pg_qsort(void *base, size_t nel, size_t elsize, int (*cmp) (const void *, const void *)); -extern int pg_qsort_strcmp(const void *a, const void *b); +extern void qsort_strcmp(void *base, size_t nel, size_t elsize); #define qsort(a,b,c,d) pg_qsort(a,b,c,d) diff --git a/src/port/qsort.c b/src/port/qsort.c index 7879e6cd56..ca30df5bc6 100644 --- a/src/port/qsort.c +++ b/src/port/qsort.c @@ -12,11 +12,11 @@ #define ST_DEFINE #include "lib/sort_template.h" -/* - * qsort comparator wrapper for strcmp. - */ -int -pg_qsort_strcmp(const void *a, const void *b) -{ - return strcmp(*(const char *const *) a, *(const char *const *) b); -} +#define ST_SORT qsort_strcmp +#define ST_ELEMENT_TYPE_VOID +#define ST_COMPARE(a, b) \ + strcmp(*(const char *const *) (a), *(const char *const *) (b)) +#define ST_SCOPE extern +#define ST_DECLARE +#define ST_DEFINE +#include "lib/sort_template.h" --Apple-Mail=_EE7C281A-2743-43FA-A5BE-956125888AA8--