From d69046e5f6d9c570aafa54bf3a99eb9d63fd439e Mon Sep 17 00:00:00 2001 From: Nathan Bossart Date: Thu, 7 Dec 2023 16:45:45 -0600 Subject: [PATCH v1 1/1] avoid some strlen() calls in json.c --- src/backend/utils/adt/json.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/backend/utils/adt/json.c b/src/backend/utils/adt/json.c index cb4311e75f..b22d9d5b4c 100644 --- a/src/backend/utils/adt/json.c +++ b/src/backend/utils/adt/json.c @@ -178,6 +178,7 @@ datum_to_json_internal(Datum val, bool is_null, StringInfo result, { char *outputstr; text *jsontext; + int len; check_stack_depth(); @@ -220,9 +221,12 @@ datum_to_json_internal(Datum val, bool is_null, StringInfo result, /* * Don't call escape_json for a non-key if it's a valid JSON * number. + * + * Saving the strlen() result allows us to avoid another expensive + * strlen() call in appendStringInfoString(). */ - if (!key_scalar && IsValidJsonNumber(outputstr, strlen(outputstr))) - appendStringInfoString(result, outputstr); + if (!key_scalar && IsValidJsonNumber(outputstr, (len = strlen(outputstr)))) + appendBinaryStringInfo(result, outputstr, len); else escape_json(result, outputstr); pfree(outputstr); @@ -502,8 +506,14 @@ composite_to_json(Datum composite, StringInfo result, bool use_line_feeds) int i; bool needsep = false; const char *sep; + int seplen; + /* + * We can avoid expensive strlen() calls by precalculating the separator + * length. + */ sep = use_line_feeds ? ",\n " : ","; + seplen = use_line_feeds ? sizeof(",\n ") - 1 : sizeof(",") - 1; td = DatumGetHeapTupleHeader(composite); @@ -532,7 +542,7 @@ composite_to_json(Datum composite, StringInfo result, bool use_line_feeds) continue; if (needsep) - appendStringInfoString(result, sep); + appendBinaryStringInfo(result, sep, seplen); needsep = true; attname = NameStr(att->attname); -- 2.25.1