From ab8ba71b018423779289c442f05a369e373dc41d Mon Sep 17 00:00:00 2001
From: John Naylor <john.naylor@postgresql.org>
Date: Sat, 14 Feb 2026 11:41:34 +0700
Subject: [PATCH v8 2/4] Detect common prefix to avoid wasted work during radix
 sort

Start radix sort at the most significant byte position that has more
than one distinct byte in the input. This skips passes where radix
sort would count the distinct bytes just to find only a single one,
in which case there is nothing further to do for that pass. This can
give a few percent speedup for integers that have some zero upper
bytes, which is common for those that didn't arrive via abbreviation.

Reviewed-by: Chengpeng Yan <chengpeng_yan@outlook.com>
Discussion: https://postgr.es/m/CANWCAZYpGMDSSwAa18fOxJGXaPzVdyPsWpOkfCX32DWh3Qznzw@mail.gmail.com
---
 src/backend/utils/sort/tuplesort.c | 48 ++++++++++++++++++++++++++----
 1 file changed, 43 insertions(+), 5 deletions(-)

diff --git a/src/backend/utils/sort/tuplesort.c b/src/backend/utils/sort/tuplesort.c
index 1fc440ea6ca..2203cfb725d 100644
--- a/src/backend/utils/sort/tuplesort.c
+++ b/src/backend/utils/sort/tuplesort.c
@@ -104,6 +104,7 @@
 #include "commands/tablespace.h"
 #include "miscadmin.h"
 #include "pg_trace.h"
+#include "port/pg_bitutils.h"
 #include "storage/shmem.h"
 #include "utils/guc.h"
 #include "utils/memutils.h"
@@ -2909,28 +2910,65 @@ radix_sort_tuple(SortTuple *data, size_t n, Tuplesortstate *state)
 	}
 	else
 	{
+		int			common_prefix;
+		Datum		ref_datum;
+		Datum		common_upper_bits = 0;
 		bool		presorted = true;
 
+		Assert(not_null_count > 0);
+		ref_datum = not_null_start[0].datum1;
+
+		/* compute the common prefix of all datums */
 		for (SortTuple *st = not_null_start + 1;
 			 st < not_null_start + not_null_count;
 			 st++)
 		{
-			if (COMPARETUP(state, st - 1, st) > 0)
-			{
+			Datum		this_datum = st->datum1;
+
+			/*
+			 * Accumulate bits that represent a difference from the reference
+			 * datum.
+			 */
+			common_upper_bits |= ref_datum ^ this_datum;
+
+			/* do a presorted check while we're at it */
+			if (presorted && COMPARETUP(state, st - 1, st) > 0)
 				presorted = false;
-				break;
-			}
 
 			CHECK_FOR_INTERRUPTS();
 		}
 
 		if (presorted)
 			return;
+		else if (common_upper_bits == 0)
+		{
+			/*
+			 * All NOT NULL tuples have the same datum, so we can skip radix
+			 * sort. Sort using the tiebreak comparator if necessary.
+			 */
+			if (state->base.onlyKey == NULL)
+			{
+				qsort_tuple(not_null_start,
+							not_null_count,
+							state->base.comparetup_tiebreak,
+							state);
+			}
+		}
 		else
 		{
+			int			diffpos;
+
+			/*
+			 * The upper bits of common_upper_bits are zero where all datums
+			 * have the same bits. The byte position of the leftmost one bit
+			 * is the byte where radix sort should start.
+			 */
+			diffpos = pg_leftmost_one_pos64(DatumGetUInt64(common_upper_bits));
+			common_prefix = sizeof(Datum) - 1 - (diffpos / BITS_PER_BYTE);
+
 			radix_sort_recursive(not_null_start,
 								 not_null_count,
-								 0,
+								 common_prefix,
 								 state);
 		}
 	}
-- 
2.53.0

