On Sat, Jan 11, 2020 at 03:19:37PM -0500, Tom Lane wrote: > Jeff Janes <jeff.ja...@gmail.com> writes: > > I saw that the hotspot was pq_begintypsend at 20%, which was twice the > > percentage as the next place winner (AllocSetAlloc). > > Weird. > > > Why is this such a bottleneck? > > Not sure, but it seems like a pretty dumb way to push the stringinfo's > len forward. We're reading/updating the len word in each line, and > if your perf measurements are to be believed, it's the re-fetches of > the len values that are bottlenecked --- maybe your CPU isn't too > bright about that? The bytes of the string value are getting written > twice too, thanks to uselessly setting up a terminating nul each time. > > I'd be inclined to replace the appendStringInfoCharMacro calls with > appendStringInfoSpaces(buf, 4) --- I don't think we care exactly what > is inserted into those bytes at this point. And maybe > appendStringInfoSpaces could stand some micro-optimization, too. > Use a memset and a single len adjustment, perhaps?
Please find attached a patch that does it both of the things you suggested. Best, David. -- David Fetter <david(at)fetter(dot)org> http://fetter.org/ Phone: +1 415 235 3778 Remember to vote! Consider donating to Postgres: http://www.postgresql.org/about/donate
>From 0c242cfd6e09d377f75febec0adaa705ff27c7f0 Mon Sep 17 00:00:00 2001 From: David Fetter <da...@fetter.org> Date: Sat, 11 Jan 2020 17:38:12 -0800 Subject: [PATCH v1] Make pq_begintypsend more efficient To: hackers MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="------------2.24.1" This is a multi-part message in MIME format. --------------2.24.1 Content-Type: text/plain; charset=UTF-8; format=fixed Content-Transfer-Encoding: 8bit by replacing 4 calls to appendStringInfoCharMacro with one call to appendStringInfoSpaces. In passing, make appendStringInfoSpaces more efficient by turning a while() loop into a memset() + increment. diff --git a/src/backend/libpq/pqformat.c b/src/backend/libpq/pqformat.c index a6f990c2d2..a4c6cdab80 100644 --- a/src/backend/libpq/pqformat.c +++ b/src/backend/libpq/pqformat.c @@ -329,10 +329,7 @@ pq_begintypsend(StringInfo buf) { initStringInfo(buf); /* Reserve four bytes for the bytea length word */ - appendStringInfoCharMacro(buf, '\0'); - appendStringInfoCharMacro(buf, '\0'); - appendStringInfoCharMacro(buf, '\0'); - appendStringInfoCharMacro(buf, '\0'); + appendStringInfoSpaces(buf, 4); } /* -------------------------------- diff --git a/src/common/stringinfo.c b/src/common/stringinfo.c index 0badc46554..87074af476 100644 --- a/src/common/stringinfo.c +++ b/src/common/stringinfo.c @@ -211,8 +211,8 @@ appendStringInfoSpaces(StringInfo str, int count) enlargeStringInfo(str, count); /* OK, append the spaces */ - while (--count >= 0) - str->data[str->len++] = ' '; + memset(&str->data[str->len], ' ', count); + str->len += count; str->data[str->len] = '\0'; } } --------------2.24.1--