diff options
author | John Naylor <john.naylor@postgresql.org> | 2022-04-02 15:22:25 +0700 |
---|---|---|
committer | John Naylor <john.naylor@postgresql.org> | 2022-04-02 15:22:25 +0700 |
commit | 6974924347c908335607a4a2f252213d58e21b7c (patch) | |
tree | aa8d5fa5f4aba89f846957410dc0176556180397 /src/include/utils/sortsupport.h | |
parent | db086de5abe5d87b07cddd030092b1f81f99c5ea (diff) | |
download | postgresql-6974924347c908335607a4a2f252213d58e21b7c.tar.gz postgresql-6974924347c908335607a4a2f252213d58e21b7c.zip |
Specialize tuplesort routines for different kinds of abbreviated keys
Previously, the specialized tuplesort routine inlined handling for
reverse-sort and NULLs-ordering but called the datum comparator via a
pointer in the SortSupport struct parameter. Testing has showed that we
can get a useful performance gain by specializing datum comparison for
the different representations of abbreviated keys -- signed and unsigned
64-bit integers and signed 32-bit integers. Almost all abbreviatable data
types will benefit -- the only exception for now is numeric, since the
datum comparison is more complex. The performance gain depends on data
type and input distribution, but often falls in the range of 10-20% faster.
Thomas Munro
Reviewed by Peter Geoghegan, review and performance testing by me
Discussion:
https://www.postgresql.org/message-id/CA%2BhUKGKKYttZZk-JMRQSVak%3DCXSJ5fiwtirFf%3Dn%3DPAbumvn1Ww%40mail.gmail.com
Diffstat (limited to 'src/include/utils/sortsupport.h')
-rw-r--r-- | src/include/utils/sortsupport.h | 115 |
1 files changed, 115 insertions, 0 deletions
diff --git a/src/include/utils/sortsupport.h b/src/include/utils/sortsupport.h index 6e3cab82d25..60e5f9940d4 100644 --- a/src/include/utils/sortsupport.h +++ b/src/include/utils/sortsupport.h @@ -229,6 +229,112 @@ ApplySortComparator(Datum datum1, bool isNull1, return compare; } +static inline int +ApplyUnsignedSortComparator(Datum datum1, bool isNull1, + Datum datum2, bool isNull2, + SortSupport ssup) +{ + int compare; + + if (isNull1) + { + if (isNull2) + compare = 0; /* NULL "=" NULL */ + else if (ssup->ssup_nulls_first) + compare = -1; /* NULL "<" NOT_NULL */ + else + compare = 1; /* NULL ">" NOT_NULL */ + } + else if (isNull2) + { + if (ssup->ssup_nulls_first) + compare = 1; /* NOT_NULL ">" NULL */ + else + compare = -1; /* NOT_NULL "<" NULL */ + } + else + { + compare = datum1 < datum2 ? -1 : datum1 > datum2 ? 1 : 0; + if (ssup->ssup_reverse) + INVERT_COMPARE_RESULT(compare); + } + + return compare; +} + +static inline int +ApplySignedSortComparator(Datum datum1, bool isNull1, + Datum datum2, bool isNull2, + SortSupport ssup) +{ + int compare; + + if (isNull1) + { + if (isNull2) + compare = 0; /* NULL "=" NULL */ + else if (ssup->ssup_nulls_first) + compare = -1; /* NULL "<" NOT_NULL */ + else + compare = 1; /* NULL ">" NOT_NULL */ + } + else if (isNull2) + { + if (ssup->ssup_nulls_first) + compare = 1; /* NOT_NULL ">" NULL */ + else + compare = -1; /* NOT_NULL "<" NULL */ + } + else + { +#if SIZEOF_DATUM == 8 + compare = (int64) datum1 < (int64) datum2 ? -1 : + (int64) datum1 > (int64) datum2 ? 1 : 0; +#else + compare = (int32) datum1 < (int32) datum2 ? -1 : + (int32) datum1 > (int32) datum2 ? 1 : 0; +#endif + if (ssup->ssup_reverse) + INVERT_COMPARE_RESULT(compare); + } + + return compare; +} + +static inline int +ApplyInt32SortComparator(Datum datum1, bool isNull1, + Datum datum2, bool isNull2, + SortSupport ssup) +{ + int compare; + + if (isNull1) + { + if (isNull2) + compare = 0; /* NULL "=" NULL */ + else if (ssup->ssup_nulls_first) + compare = -1; /* NULL "<" NOT_NULL */ + else + compare = 1; /* NULL ">" NOT_NULL */ + } + else if (isNull2) + { + if (ssup->ssup_nulls_first) + compare = 1; /* NOT_NULL ">" NULL */ + else + compare = -1; /* NOT_NULL "<" NULL */ + } + else + { + compare = (int32) datum1 < (int32) datum2 ? -1 : + (int32) datum1 > (int32) datum2 ? 1 : 0; + if (ssup->ssup_reverse) + INVERT_COMPARE_RESULT(compare); + } + + return compare; +} + /* * Apply a sort comparator function and return a 3-way comparison using full, * authoritative comparator. This takes care of handling reverse-sort and @@ -267,6 +373,15 @@ ApplySortAbbrevFullComparator(Datum datum1, bool isNull1, return compare; } +/* + * Datum comparison functions that we have specialized sort routines for. + * Datatypes that install these as their comparator or abbrevated comparator + * are eligible for faster sorting. + */ +extern int ssup_datum_unsigned_cmp(Datum x, Datum y, SortSupport ssup); +extern int ssup_datum_signed_cmp(Datum x, Datum y, SortSupport ssup); +extern int ssup_datum_int32_cmp(Datum x, Datum y, SortSupport ssup); + /* Other functions in utils/sort/sortsupport.c */ extern void PrepareSortSupportComparisonShim(Oid cmpFunc, SortSupport ssup); extern void PrepareSortSupportFromOrderingOp(Oid orderingOp, SortSupport ssup); |