aboutsummaryrefslogtreecommitdiff
path: root/src/common/binaryheap.c
diff options
context:
space:
mode:
authorNathan Bossart <nathan@postgresql.org>2024-10-30 11:28:34 -0500
committerNathan Bossart <nathan@postgresql.org>2024-10-30 11:28:34 -0500
commit849110dd3eec3e21c358e24f11c6d501d05eee72 (patch)
tree5b39238872860c9b19802531a81bc9ceac59e097 /src/common/binaryheap.c
parentaf21152268317323480caa790c4a6347110f8085 (diff)
downloadpostgresql-849110dd3eec3e21c358e24f11c6d501d05eee72.tar.gz
postgresql-849110dd3eec3e21c358e24f11c6d501d05eee72.zip
Optimize sifting down in binaryheap.
Presently, each iteration of the loop in sift_down() will perform 3 comparisons if both children are larger than the parent node (2 for comparing each child to the parent node, and a third to compare the children to each other). By first comparing the children to each other and then comparing the larger child to the parent node, we can accomplish the same thing with just 2 comparisons (while also not affecting the number of comparisons in any other case). Author: ChangAo Chen Reviewed-by: Robert Haas Discussion: https://postgr.es/m/tencent_0142D8DA90940B9930BCC08348BBD6D0BB07%40qq.com
Diffstat (limited to 'src/common/binaryheap.c')
-rw-r--r--src/common/binaryheap.c29
1 files changed, 9 insertions, 20 deletions
diff --git a/src/common/binaryheap.c b/src/common/binaryheap.c
index 7377ebdf156..159a316c221 100644
--- a/src/common/binaryheap.c
+++ b/src/common/binaryheap.c
@@ -323,34 +323,23 @@ sift_down(binaryheap *heap, int node_off)
{
int left_off = left_offset(node_off);
int right_off = right_offset(node_off);
- int swap_off = 0;
+ int swap_off = left_off;
- /* Is the left child larger than the parent? */
- if (left_off < heap->bh_size &&
- heap->bh_compare(node_val,
- heap->bh_nodes[left_off],
- heap->bh_arg) < 0)
- swap_off = left_off;
-
- /* Is the right child larger than the parent? */
+ /* Is the right child larger than the left child? */
if (right_off < heap->bh_size &&
- heap->bh_compare(node_val,
+ heap->bh_compare(heap->bh_nodes[left_off],
heap->bh_nodes[right_off],
heap->bh_arg) < 0)
- {
- /* swap with the larger child */
- if (!swap_off ||
- heap->bh_compare(heap->bh_nodes[left_off],
- heap->bh_nodes[right_off],
- heap->bh_arg) < 0)
- swap_off = right_off;
- }
+ swap_off = right_off;
/*
- * If we didn't find anything to swap, the heap condition is
+ * If no children or parent is >= the larger child, heap condition is
* satisfied, and we're done.
*/
- if (!swap_off)
+ if (left_off >= heap->bh_size ||
+ heap->bh_compare(node_val,
+ heap->bh_nodes[swap_off],
+ heap->bh_arg) >= 0)
break;
/*