src/port/snprintf.c: Optimize the common base=10 case in fmtint

From: Arjan van de Ven <arjan(at)linux(dot)intel(dot)com>
To: pgsql-hackers(at)postgresql(dot)org
Subject: src/port/snprintf.c: Optimize the common base=10 case in fmtint
Date: 2021-10-26 14:57:36
Message-ID: 40a4b32a-b841-4667-11b2-a0baedb12714@linux.intel.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

src/port/snprintf.c: Optimize the common base=10 case in fmtint

fmtint() turns an integer into a string for a given base, and to do this
it does a divide/modulo operation iteratively.

On just about any CPU, divides are a pretty expensive operation, generally
10x to 20x or more expensive than adds or multiplies.

By special casing the super common case of base==10, the (gcc) compiler can (and will)
replace the divide by a multiply with 0xcccccccccccccccd, yielding a lot faster code.
(fmtint dropped drastically in the perf profiles after this change)

Even though this only shows up in the database creation phase of pgbench and not so much
during the normal run time, the optimization is simple and high value enough that
in my opinion it's worth doing

diff --git a/src/port/snprintf.c b/src/port/snprintf.c
index 7c21429369..5957e6f2aa 100644
--- a/src/port/snprintf.c
+++ b/src/port/snprintf.c
@@ -1076,11 +1076,24 @@ fmtint(long long value, char type, int forcesign, int leftjust,
else
{
/* make integer string */
- do
- {
- convert[sizeof(convert) - (++vallen)] = cvt[uvalue % base];
- uvalue = uvalue / base;
- } while (uvalue);
+
+ /*
+ * Special case a base of 10 because it is super common and by special casing the compiler can
+ * avoid an expensive divide operation (the compiler will use a multiply for this)
+ */
+ if (likely(base == 10)) {
+ do
+ {
+ convert[sizeof(convert) - (++vallen)] = cvt[uvalue % 10];
+ uvalue = uvalue / 10;
+ } while (uvalue);
+ } else {
+ do
+ {
+ convert[sizeof(convert) - (++vallen)] = cvt[uvalue % base];
+ uvalue = uvalue / base;
+ } while (uvalue);
+ }
}

zeropad = Max(0, precision - vallen);

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Robert Haas 2021-10-26 15:03:44 Re: Refactoring: join MakeSingleTupleTableSlot() and MakeTupleTableSlot()
Previous Message Fujii Masao 2021-10-26 14:32:00 Re: Allow pg_signal_backend members to use pg_log_backend_memory_stats().