From 4c404d3074d33e1f56e95abc5037f20816727235 Mon Sep 17 00:00:00 2001 From: Yuya Watari Date: Tue, 14 Mar 2023 15:12:18 +0900 Subject: [PATCH v2] Remove bms_is_empty_internal() function calls Originally, we checked whether the result of the Bitmapset operation was empty or not by calling the bms_is_empty_internal() function. However, these calls lead to unnecessary looping over the result Bitmapset. This commit reduces such redundant calls and improves the performance. --- src/backend/nodes/bitmapset.c | 42 ++++++++++++++++++++++++++++++----- 1 file changed, 36 insertions(+), 6 deletions(-) diff --git a/src/backend/nodes/bitmapset.c b/src/backend/nodes/bitmapset.c index 7ba3cf635b..47eec5b63b 100644 --- a/src/backend/nodes/bitmapset.c +++ b/src/backend/nodes/bitmapset.c @@ -263,6 +263,7 @@ bms_intersect(const Bitmapset *a, const Bitmapset *b) const Bitmapset *other; int resultlen; int i; + bitmapword bitwise_or = 0; /* Handle cases where either input is NULL */ if (a == NULL || b == NULL) @@ -281,9 +282,17 @@ bms_intersect(const Bitmapset *a, const Bitmapset *b) /* And intersect the longer input with the result */ resultlen = result->nwords; for (i = 0; i < resultlen; i++) - result->words[i] &= other->words[i]; + { + bitmapword w = (result->words[i] &= other->words[i]); + + /* + * Compute bitwise OR of all bitmapwords to determine if the result + * is empty + */ + bitwise_or |= w; + } /* If we computed an empty result, we must return NULL */ - if (bms_is_empty_internal(result)) + if (bitwise_or == 0) { pfree(result); return NULL; @@ -929,6 +938,7 @@ bms_int_members(Bitmapset *a, const Bitmapset *b) { int shortlen; int i; + bitmapword bitwise_or = 0; /* Handle cases where either input is NULL */ if (a == NULL) @@ -941,11 +951,19 @@ bms_int_members(Bitmapset *a, const Bitmapset *b) /* Intersect b into a; we need never copy */ shortlen = Min(a->nwords, b->nwords); for (i = 0; i < shortlen; i++) - a->words[i] &= b->words[i]; + { + bitmapword w = (a->words[i] &= b->words[i]); + + /* + * Compute bitwise OR of all bitmapwords to determine if the result + * is empty + */ + bitwise_or |= w; + } for (; i < a->nwords; i++) a->words[i] = 0; /* If we computed an empty result, we must return NULL */ - if (bms_is_empty_internal(a)) + if (bitwise_or == 0) { pfree(a); return NULL; @@ -961,6 +979,7 @@ bms_del_members(Bitmapset *a, const Bitmapset *b) { int shortlen; int i; + bitmapword bitwise_or = 0; /* Handle cases where either input is NULL */ if (a == NULL) @@ -970,9 +989,20 @@ bms_del_members(Bitmapset *a, const Bitmapset *b) /* Remove b's bits from a; we need never copy */ shortlen = Min(a->nwords, b->nwords); for (i = 0; i < shortlen; i++) - a->words[i] &= ~b->words[i]; + { + bitmapword w = (a->words[i] &= ~b->words[i]); + + /* + * Compute bitwise OR of all bitmapwords to determine if the result + * is empty + */ + bitwise_or |= w; + } + /* Compute bitwise OR of extra words in a */ + for (; i < a->nwords; i++) + bitwise_or |= a->words[i]; /* If we computed an empty result, we must return NULL */ - if (bms_is_empty_internal(a)) + if (bitwise_or == 0) { pfree(a); return NULL; -- 2.39.2.windows.1