Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit4fc115b

Browse files
committed
Speed up conversion of signed integers to C strings.
A hand-coded implementation turns out to be much faster than callingprintf(). In passing, add a few more regresion tests.Andres Freund, with assorted, mostly cosmetic changes.
1 parent0f61d4d commit4fc115b

File tree

9 files changed

+157
-18
lines changed

9 files changed

+157
-18
lines changed

‎src/backend/utils/adt/int8.c

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include"funcapi.h"
2121
#include"libpq/pqformat.h"
2222
#include"utils/int8.h"
23+
#include"utils/builtins.h"
2324

2425

2526
#defineMAXINT8LEN25
@@ -157,13 +158,10 @@ Datum
157158
int8out(PG_FUNCTION_ARGS)
158159
{
159160
int64val=PG_GETARG_INT64(0);
160-
char*result;
161-
intlen;
162161
charbuf[MAXINT8LEN+1];
162+
char*result;
163163

164-
if ((len=snprintf(buf,MAXINT8LEN,INT64_FORMAT,val))<0)
165-
elog(ERROR,"could not format int8");
166-
164+
pg_lltoa(val,buf);
167165
result=pstrdup(buf);
168166
PG_RETURN_CSTRING(result);
169167
}

‎src/backend/utils/adt/numutils.c

Lines changed: 102 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,6 @@
33
* numutils.c
44
* utility functions for I/O of built-in numeric types.
55
*
6-
*integer:pg_atoi, pg_itoa, pg_ltoa
7-
*
86
* Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
97
* Portions Copyright (c) 1994, Regents of the University of California
108
*
@@ -109,27 +107,118 @@ pg_atoi(char *s, int size, int c)
109107
}
110108

111109
/*
112-
*pg_itoa- converts a short int to its string represention
110+
* pg_itoa: converts a signed 16-bit integer to its string representation
111+
*
112+
* Caller must ensure that 'a' points to enough memory to hold the result
113+
* (at least 7 bytes, counting a leading sign and trailing NUL).
113114
*
114-
*Note:
115-
*previously based on ~ingres/source/gutil/atoi.c
116-
*now uses vendor's sprintf conversion
115+
* It doesn't seem worth implementing this separately.
117116
*/
118117
void
119118
pg_itoa(int16i,char*a)
120119
{
121-
sprintf(a,"%hd", (short)i);
120+
pg_ltoa((int32)i,a);
121+
}
122+
123+
/*
124+
* pg_ltoa: converts a signed 32-bit integer to its string representation
125+
*
126+
* Caller must ensure that 'a' points to enough memory to hold the result
127+
* (at least 12 bytes, counting a leading sign and trailing NUL).
128+
*/
129+
void
130+
pg_ltoa(int32value,char*a)
131+
{
132+
char*start=a;
133+
boolneg= false;
134+
135+
/*
136+
* Avoid problems with the most negative integer not being representable
137+
* as a positive integer.
138+
*/
139+
if (value==INT32_MIN)
140+
{
141+
memcpy(a,"-2147483648",12);
142+
return;
143+
}
144+
elseif (value<0)
145+
{
146+
value=-value;
147+
neg= true;
148+
}
149+
150+
/* Compute the result backwards. */
151+
do
152+
{
153+
int32remainder;
154+
int32oldval=value;
155+
value /=10;
156+
remainder=oldval-value*10;
157+
*a++='0'+remainder;
158+
}while (value!=0);
159+
if (neg)
160+
*a++='-';
161+
162+
/* Add trailing NUL byte. */
163+
*a--='\0';
164+
165+
/* reverse string */
166+
while (start<a)
167+
{
168+
charswap=*start;
169+
*start++=*a;
170+
*a--=swap;
171+
}
122172
}
123173

124174
/*
125-
*pg_ltoa- converts a long intto its stringrepresention
175+
* pg_lltoa: convert a signed 64bit integerto its stringrepresentation
126176
*
127-
*Note:
128-
*previously based on ~ingres/source/gutil/atoi.c
129-
*now uses vendor's sprintf conversion
177+
* Caller must ensure that 'a' points to enough memory to hold the result
178+
* (at least MAXINT8LEN+1 bytes, counting a leading sign and trailing NUL).
130179
*/
131180
void
132-
pg_ltoa(int32l,char*a)
181+
pg_lltoa(int64value,char*a)
133182
{
134-
sprintf(a,"%d",l);
183+
char*start=a;
184+
boolneg= false;
185+
186+
/*
187+
* Avoid problems with the most negative integer not being representable
188+
* as a positive integer.
189+
*/
190+
if (value==INT64_MIN)
191+
{
192+
memcpy(a,"-9223372036854775808",21);
193+
return;
194+
}
195+
elseif (value<0)
196+
{
197+
value=-value;
198+
neg= true;
199+
}
200+
201+
/* Build the string by computing the wanted string backwards. */
202+
do
203+
{
204+
int64remainder;
205+
int64oldval=value;
206+
value /=10;
207+
remainder=oldval-value*10;
208+
*a++='0'+remainder;
209+
}while (value!=0);
210+
211+
if (neg)
212+
*a++='-';
213+
214+
/* Add trailing NUL byte. */
215+
*a--='\0';
216+
217+
/* Reverse string. */
218+
while (start<a)
219+
{
220+
charswap=*start;
221+
*start++=*a;
222+
*a--=swap;
223+
}
135224
}

‎src/include/utils/builtins.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,7 @@ extern Datum current_schemas(PG_FUNCTION_ARGS);
275275
externint32pg_atoi(char*s,intsize,intc);
276276
externvoidpg_itoa(int16i,char*a);
277277
externvoidpg_ltoa(int32l,char*a);
278+
externvoidpg_lltoa(int64ll,char*a);
278279

279280
/*
280281
*Per-opclass comparison functions for new btrees. These are

‎src/test/regress/expected/int2.out

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,3 +242,16 @@ SELECT '' AS five, i.f1, i.f1 / int4 '2' AS x FROM INT2_TBL i;
242242
| -32767 | -16383
243243
(5 rows)
244244

245+
-- corner cases
246+
SELECT (1<<15-1)::int2::text;
247+
text
248+
-------
249+
16384
250+
(1 row)
251+
252+
SELECT (-1<<15)::int2::text;
253+
text
254+
--------
255+
-32768
256+
(1 row)
257+

‎src/test/regress/expected/int4.out

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -329,3 +329,16 @@ SELECT (2 + 2) / 2 AS two;
329329
2
330330
(1 row)
331331

332+
-- corner cases
333+
SELECT (1<<31-1)::int4::text;
334+
text
335+
------------
336+
1073741824
337+
(1 row)
338+
339+
SELECT (1<<31)::int4::text;
340+
text
341+
-------------
342+
-2147483648
343+
(1 row)
344+

‎src/test/regress/expected/int8.out

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -802,3 +802,16 @@ SELECT * FROM generate_series('+4567890123456789'::int8, '+4567890123456799'::in
802802
4567890123456799
803803
(6 rows)
804804

805+
-- corner cases
806+
SELECT (1<<63-1)::int8::text;
807+
text
808+
------------
809+
1073741824
810+
(1 row)
811+
812+
SELECT (1<<63)::int8::text;
813+
text
814+
-------------
815+
-2147483648
816+
(1 row)
817+

‎src/test/regress/sql/int2.sql

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,3 +83,7 @@ SELECT '' AS five, i.f1, i.f1 - int4 '2' AS x FROM INT2_TBL i;
8383
SELECT''AS five,i.f1,i.f1/ int2'2'AS xFROM INT2_TBL i;
8484

8585
SELECT''AS five,i.f1,i.f1/ int4'2'AS xFROM INT2_TBL i;
86+
87+
-- corner cases
88+
SELECT (1<<15-1)::int2::text;
89+
SELECT (-1<<15)::int2::text;

‎src/test/regress/sql/int4.sql

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,3 +123,7 @@ SELECT 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 AS ten;
123123
SELECT2+2/2AS three;
124124

125125
SELECT (2+2)/2AS two;
126+
127+
-- corner cases
128+
SELECT (1<<31-1)::int4::text;
129+
SELECT (1<<31)::int4::text;

‎src/test/regress/sql/int8.sql

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,3 +190,7 @@ SELECT q1, q1 << 2 AS "shl", q1 >> 3 AS "shr" FROM INT8_TBL;
190190
SELECT*FROM generate_series('+4567890123456789'::int8,'+4567890123456799'::int8);
191191
SELECT*FROM generate_series('+4567890123456789'::int8,'+4567890123456799'::int8,0);
192192
SELECT*FROM generate_series('+4567890123456789'::int8,'+4567890123456799'::int8,2);
193+
194+
-- corner cases
195+
SELECT (1<<63-1)::int8::text;
196+
SELECT (1<<63)::int8::text;

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp