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

Commitdc3f9bc

Browse files
Micro-optimize JSONTYPE_NUMERIC code path in json.c.
This commit does the following:* In datum_to_json_internal(), the call to IsValidJsonNumber() is replaced with simplified validation code. This avoids an extra call to strlen() in this path, and it avoids validating the entire string (which is okay since we know we're dealing with a numeric data type's output).* In datum_to_json_internal(), the call to escape_json() in the JSONTYPE_NUMERIC path is replaced with code that just surrounds the string with quotes. In passing, some other nearby calls to appendStringInfo() have been replaced with similar code to avoid unnecessary calls to vsnprintf().* In composite_to_json(), the length of the separator is now determined at compile time to avoid unnecessary calls to strlen().On my machine, this speeds up a benchmark for the proposed COPY TO(FORMAT json) command with many integers by upwards of 20%. Thereare likely other code paths that could be given a similartreatment, but that is left as a future exercise.Reviewed-by: Jeff Davis, Tom Lane, David Rowley, John NaylorDiscussion:https://postgr.es/m/20231207231251.GB3359478%40nathanxps13
1 parent867dd2d commitdc3f9bc

File tree

1 file changed

+29
-8
lines changed

1 file changed

+29
-8
lines changed

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

Lines changed: 29 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -220,37 +220,52 @@ datum_to_json_internal(Datum val, bool is_null, StringInfo result,
220220
outputstr=OidOutputFunctionCall(outfuncoid,val);
221221

222222
/*
223-
* Don't call escape_json for a non-key if it's a valid JSON
224-
* number.
223+
* Don't quote a non-key if it's a valid JSON number (i.e., not
224+
* "Infinity", "-Infinity", or "NaN"). Since we know this is a
225+
* numeric data type's output, we simplify and open-code the
226+
* validation for better performance.
225227
*/
226-
if (!key_scalar&&IsValidJsonNumber(outputstr,strlen(outputstr)))
228+
if (!key_scalar&&
229+
((*outputstr >='0'&&*outputstr <='9')||
230+
(*outputstr=='-'&&
231+
(outputstr[1] >='0'&&outputstr[1] <='9'))))
227232
appendStringInfoString(result,outputstr);
228233
else
229-
escape_json(result,outputstr);
234+
{
235+
appendStringInfoChar(result,'"');
236+
appendStringInfoString(result,outputstr);
237+
appendStringInfoChar(result,'"');
238+
}
230239
pfree(outputstr);
231240
break;
232241
caseJSONTYPE_DATE:
233242
{
234243
charbuf[MAXDATELEN+1];
235244

236245
JsonEncodeDateTime(buf,val,DATEOID,NULL);
237-
appendStringInfo(result,"\"%s\"",buf);
246+
appendStringInfoChar(result,'"');
247+
appendStringInfoString(result,buf);
248+
appendStringInfoChar(result,'"');
238249
}
239250
break;
240251
caseJSONTYPE_TIMESTAMP:
241252
{
242253
charbuf[MAXDATELEN+1];
243254

244255
JsonEncodeDateTime(buf,val,TIMESTAMPOID,NULL);
245-
appendStringInfo(result,"\"%s\"",buf);
256+
appendStringInfoChar(result,'"');
257+
appendStringInfoString(result,buf);
258+
appendStringInfoChar(result,'"');
246259
}
247260
break;
248261
caseJSONTYPE_TIMESTAMPTZ:
249262
{
250263
charbuf[MAXDATELEN+1];
251264

252265
JsonEncodeDateTime(buf,val,TIMESTAMPTZOID,NULL);
253-
appendStringInfo(result,"\"%s\"",buf);
266+
appendStringInfoChar(result,'"');
267+
appendStringInfoString(result,buf);
268+
appendStringInfoChar(result,'"');
254269
}
255270
break;
256271
caseJSONTYPE_JSON:
@@ -503,8 +518,14 @@ composite_to_json(Datum composite, StringInfo result, bool use_line_feeds)
503518
inti;
504519
boolneedsep= false;
505520
constchar*sep;
521+
intseplen;
506522

523+
/*
524+
* We can avoid expensive strlen() calls by precalculating the separator
525+
* length.
526+
*/
507527
sep=use_line_feeds ?",\n " :",";
528+
seplen=use_line_feeds ?strlen(",\n ") :strlen(",");
508529

509530
td=DatumGetHeapTupleHeader(composite);
510531

@@ -533,7 +554,7 @@ composite_to_json(Datum composite, StringInfo result, bool use_line_feeds)
533554
continue;
534555

535556
if (needsep)
536-
appendStringInfoString(result,sep);
557+
appendBinaryStringInfo(result,sep,seplen);
537558
needsep= true;
538559

539560
attname=NameStr(att->attname);

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp