Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 3c17926

Browse files
committed
Speed up printing of integers in snprintf.c.
Since the only possible divisors are 8, 10, and 16, it doesn't cost much code space to replace the division loop with three copies using constant divisors. On most machines, division by a constant can be done a lot more cheaply than division by an arbitrary value. A microbenchmark testing just snprintf("foo %d") with a 9-digit value showed about a 2X speedup for me (tgl). Most of Postgres isn't too dependent on the speed of snprintf, so that the effect in real-world cases is barely measurable. Still, a cycle saved is a cycle earned. Arjan van de Ven Discussion: https://postgr.es/m/40a4b32a-b841-4667-11b2-a0baedb12714@linux.intel.com Discussion: https://postgr.es/m/6e51c644-1b6d-956e-ac24-2d1b0541d532@linux.intel.com
1 parent 7f580aa commit 3c17926

File tree

1 file changed

+30
-6
lines changed

1 file changed

+30
-6
lines changed

src/port/snprintf.c

+30-6
Original file line numberDiff line numberDiff line change
@@ -1015,8 +1015,8 @@ fmtint(long long value, char type, int forcesign, int leftjust,
10151015
int minlen, int zpad, int precision, int pointflag,
10161016
PrintfTarget *target)
10171017
{
1018-
unsigned long long base;
10191018
unsigned long long uvalue;
1019+
int base;
10201020
int dosign;
10211021
const char *cvt = "0123456789abcdef";
10221022
int signvalue = 0;
@@ -1075,12 +1075,36 @@ fmtint(long long value, char type, int forcesign, int leftjust,
10751075
vallen = 0;
10761076
else
10771077
{
1078-
/* make integer string */
1079-
do
1078+
/*
1079+
* Convert integer to string. We special-case each of the possible
1080+
* base values so as to avoid general-purpose divisions. On most
1081+
* machines, division by a fixed constant can be done much more
1082+
* cheaply than a general divide.
1083+
*/
1084+
if (base == 10)
1085+
{
1086+
do
1087+
{
1088+
convert[sizeof(convert) - (++vallen)] = cvt[uvalue % 10];
1089+
uvalue = uvalue / 10;
1090+
} while (uvalue);
1091+
}
1092+
else if (base == 16)
10801093
{
1081-
convert[sizeof(convert) - (++vallen)] = cvt[uvalue % base];
1082-
uvalue = uvalue / base;
1083-
} while (uvalue);
1094+
do
1095+
{
1096+
convert[sizeof(convert) - (++vallen)] = cvt[uvalue % 16];
1097+
uvalue = uvalue / 16;
1098+
} while (uvalue);
1099+
}
1100+
else /* base == 8 */
1101+
{
1102+
do
1103+
{
1104+
convert[sizeof(convert) - (++vallen)] = cvt[uvalue % 8];
1105+
uvalue = uvalue / 8;
1106+
} while (uvalue);
1107+
}
10841108
}
10851109

10861110
zeropad = Max(0, precision - vallen);

0 commit comments

Comments
 (0)