From 177d013928d2bb5c0c4ee565a433bbf62481b18c Mon Sep 17 00:00:00 2001 From: David Rowley Date: Thu, 1 Dec 2022 20:36:10 +1300 Subject: [PATCH v15 1/2] Adjust bms_int_members so that it shortens the left input Prior to this change, if the left input to bms_int_members had fewer Bitmapwords than the right input, the additional words in the left input would be zeroed. Doing things this why only really makes sense if we expect to add additional words to the resulting bitmap set again later. Seemingly, most of our use cases don't add to the resulting Bitmapset, in fact, many cases are performing bms_int_members in a loop which is likely to even further increase the amount of all zero words in the set. Leaving these zero trailing words in place can cause inefficiencies in functions such as bms_is_empty and loops which loop over a set using bms_next_member when the set is left with a large number of trailing words. If there are use cases which need to add additional words again, then, repalloc has to do very little processing when the requested allocation size is <= the actual allocation size. Both AllocSetRealloc and GenerationRealloc simply just return the input pointer again. If there are any cases where we do increase the size of the set again, then this just shifts the zeroing of the additional words until then. We could give bms_del_members() and bms_difference similar treatment, but that would require additional code to record the last non-zero word after masking out the members being deleted. That seems less worthwhile as it will add cost when we're unable to trim down the number of words. --- src/backend/nodes/bitmapset.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/backend/nodes/bitmapset.c b/src/backend/nodes/bitmapset.c index 98660524ad..b13b4c378f 100644 --- a/src/backend/nodes/bitmapset.c +++ b/src/backend/nodes/bitmapset.c @@ -920,8 +920,16 @@ bms_int_members(Bitmapset *a, const Bitmapset *b) shortlen = Min(a->nwords, b->nwords); for (i = 0; i < shortlen; i++) a->words[i] &= b->words[i]; - for (; i < a->nwords; i++) - a->words[i] = 0; + + /* + * We simply shorten the left input to both remove the need to zero the + * trailing words and also to reduce the required processing if this + * function is being called in a loop. If more words are required later + * then AllocSetRealloc is likely not going to have to work very hard if + * the new requested size is >= the actual size of the allocation. + */ + a->nwords = shortlen; + return a; } -- 2.39.0.windows.1