Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1us5Ps-00HCUl-OH for pgsql-hackers@arkaria.postgresql.org; Fri, 29 Aug 2025 20:09:46 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.94.2) (envelope-from ) id 1us5Ps-00CfNE-17 for pgsql-hackers@arkaria.postgresql.org; Fri, 29 Aug 2025 20:09:44 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1us5Pr-00CfN6-Nw for pgsql-hackers@lists.postgresql.org; Fri, 29 Aug 2025 20:09:44 +0000 Received: from sss.pgh.pa.us ([68.162.161.243]) by magus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1us5Pq-002Z6c-1C for pgsql-hackers@lists.postgresql.org; Fri, 29 Aug 2025 20:09:44 +0000 Received: from sss1.sss.pgh.pa.us (localhost [127.0.0.1]) by sss.pgh.pa.us (8.15.2/8.15.2) with ESMTP id 57TK9eZb2466174; Fri, 29 Aug 2025 16:09:40 -0400 From: Tom Lane To: Chao Li cc: jian he , pgsql-hackers@lists.postgresql.org Subject: Re: Making jsonb_agg() faster In-reply-to: <2613D418-67E0-4DD8-BDA6-AB1BB04DB1A2@gmail.com> References: <1060917.1753202222@sss.pgh.pa.us> <617666.1755277022@sss.pgh.pa.us> <654628.1755297629@sss.pgh.pa.us> <2129790.1755889894@sss.pgh.pa.us> <68A1061C-81A5-46AA-AFA9-48294908254C@gmail.com> <2613D418-67E0-4DD8-BDA6-AB1BB04DB1A2@gmail.com> Comments: In-reply-to Chao Li message dated "Wed, 27 Aug 2025 09:22:17 +0800" MIME-Version: 1.0 Content-Type: text/plain; charset="UTF-8" Content-ID: <2466172.1756498180.1@sss.pgh.pa.us> Content-Transfer-Encoding: quoted-printable Date: Fri, 29 Aug 2025 16:09:40 -0400 Message-ID: <2466173.1756498180@sss.pgh.pa.us> List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk Chao Li writes: > A few more suggestions for pushJsonValue(): > ... > To push WJB_BEGIN_OBJECT and WJB_END_OBJECT, we can directly call pushJs= onValueScalar(), because once entering pushJsonbValue, they will meet the = check of (seq !=3D WJB_ELEM && seq !=3D WJB_VALUE). Directly calling push= JsonValueScalar() will saves one level of recursion. I'm not excited about that idea, because I think it'd be quite confusing for some of the calls in those stanzas to be to pushJsonbValueScalar while others are to pushJsonbValue. I don't think the recursive-push paths are particularly hot, so giving up readability to make them faster doesn't seem like the right tradeoff. There's certainly room to argue that the separation between pushJsonbValue and pushJsonbValueScalar is poorly thought out and could be done better. But I don't have a concrete idea about what it could look like instead. > And for pushJsonbValueScalar(): > - (*pstate)->size =3D 4; > + ppstate->size =3D 4; /* initial gue= ss at array size */ > Can we do lazy allocation? Initially assume size =3D 0, only allocate me= mory when pushing the first element? This way, we won=E2=80=99t allocate m= emory for empty objects and arrays. = Optimizing for the empty-array or empty-object case surely seems like the wrong thing; how often will that apply? I actually think that the initial allocation could stand to be a good bit larger, maybe 64 or 256 or so entries, to reduce the number of repallocs. I did experiment with that a little bit and could not show any definitive speedup on the test case I was using ... but 4 entries seems miserly small. regards, tom lane