Hi, On 2025-01-22 10:07:51 +0900, Amit Langote wrote: > On Fri, Jan 17, 2025 at 2:05 PM Amit Langote <amitlangot...@gmail.com> wrote: > > Here's v5 with a few commit message tweaks. > > > > Barring objections, I would like to push this early next week. > > Pushed yesterday. Thank you all.
While looking at a profile I recently noticed that ExecSeqScanWithQual() had a runtime branch to test whether qual is NULL, which seemed a bit silly. I think we should use pg_assume(), which I just added to avoid a compiler warning, to improve the code generation here. The performance gain unsurprisingly isn't significant (but seems repeatably measureable), but it does cut out a fair bit of unnecessary code. andres@awork3:/srv/dev/build/postgres/m-dev-optimize$ size executor_nodeSeqscan.c.*o text data bss dec hex filename 3330 0 0 3330 d02 executor_nodeSeqscan.c.assume.o 3834 0 0 3834 efa executor_nodeSeqscan.c.o A 13% reduction in actual code size isn't bad for such a small change, imo. I have a separate question as well - do we need to call ResetExprContext() if we neither qual, projection nor epq? I see a small gain by avoiding that. Greetings, Andres Freund
>From a443d7dc6419a5648b10bbd900acf2fc745255b4 Mon Sep 17 00:00:00 2001 From: Andres Freund <and...@anarazel.de> Date: Wed, 9 Jul 2025 19:27:19 -0400 Subject: [PATCH v1] Optimize seqscan code generation using pg_assume() Discussion: https://postgr.es/m/CA+HiwqFk-MbwhfX_kucxzL8zLmjEt9MMcHi2YF=dyhprsjs...@mail.gmail.com --- src/backend/executor/nodeSeqscan.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/backend/executor/nodeSeqscan.c b/src/backend/executor/nodeSeqscan.c index ed35c58c2c3..94047d29430 100644 --- a/src/backend/executor/nodeSeqscan.c +++ b/src/backend/executor/nodeSeqscan.c @@ -131,8 +131,12 @@ ExecSeqScanWithQual(PlanState *pstate) { SeqScanState *node = castNode(SeqScanState, pstate); + /* + * Use pg_assume() for != NULL tests to make the compiler realize no + * runtime check for the field is needed in ExecScanExtended(). + */ Assert(pstate->state->es_epq_active == NULL); - Assert(pstate->qual != NULL); + pg_assume(pstate->qual != NULL); Assert(pstate->ps_ProjInfo == NULL); return ExecScanExtended(&node->ss, @@ -153,7 +157,7 @@ ExecSeqScanWithProject(PlanState *pstate) Assert(pstate->state->es_epq_active == NULL); Assert(pstate->qual == NULL); - Assert(pstate->ps_ProjInfo != NULL); + pg_assume(pstate->ps_ProjInfo != NULL); return ExecScanExtended(&node->ss, (ExecScanAccessMtd) SeqNext, @@ -173,8 +177,8 @@ ExecSeqScanWithQualProject(PlanState *pstate) SeqScanState *node = castNode(SeqScanState, pstate); Assert(pstate->state->es_epq_active == NULL); - Assert(pstate->qual != NULL); - Assert(pstate->ps_ProjInfo != NULL); + pg_assume(pstate->qual != NULL); + pg_assume(pstate->ps_ProjInfo != NULL); return ExecScanExtended(&node->ss, (ExecScanAccessMtd) SeqNext, -- 2.48.1.76.g4e746b1a31.dirty