Re: More speedups for tuple deformation

From: David Rowley <dgrowleyml(at)gmail(dot)com>
To: Zsolt Parragi <zsolt(dot)parragi(at)percona(dot)com>
Cc: Andres Freund <andres(at)anarazel(dot)de>, John Naylor <johncnaylorls(at)gmail(dot)com>, Chao Li <li(dot)evan(dot)chao(at)gmail(dot)com>, PostgreSQL Developers <pgsql-hackers(at)lists(dot)postgresql(dot)org>
Subject: Re: More speedups for tuple deformation
Date: 2026-02-25 00:39:48
Message-ID: CAApHDvot9-P3790zcqVbaumyD2TqWg=_=PUe9OsN5+-wXQRPWw@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

Thanks for having a look at this.

On Wed, 25 Feb 2026 at 07:33, Zsolt Parragi <zsolt(dot)parragi(at)percona(dot)com> wrote:
> + * We expect that 'bits' contains at least one 0 bit somewhere in the mask,
> + * not necessarily < natts.
> + */
>
> Is this precondition really enough?
>
> Let's say we have 20 attributes, only attribute 20 is NULL
> Caller requests natts=8
>
> That sets lastByte = 1, loop only checks bits[0], which is 0xFF, exits
> with bytenum=1, bits[1] is also 0xFF
>
> Then we execute
>
> + res += pg_rightmost_one_pos32(~bits[bytenum]);
>
> where ~0xFF = 0

I think this works ok in v9, but in v10 I've added a cast so that line becomes:

res += pg_rightmost_one_pos32(~((uint32) bits[bytenum]));

For the case you describe, 0xFF becomes 0xFFFFFF00 and
pg_rightmost_one_pos32() returns 8, the lowest bit of the 2nd byte.

> + /* convert the lower 4 bits of null bitmap word into 32 bit int */
> + isnull_8 = (nullbyte & 0xf) * SPREAD_BITS_MULTIPLIER_32;
> +
> + /*
> + * convert the upper 4 bits of null bitmap word into 32 bit int, shift
> + * into the upper 32 bit
> + */
> + isnull_8 |= ((uint64) ((nullbyte >> 4) * SPREAD_BITS_MULTIPLIER_32)) << 32;
> +
> + /* mask out all other bits apart from the lowest bit of each byte */
> + isnull_8 &= UINT64CONST(0x0101010101010101);
> + memcpy(isnull, &isnull_8, sizeof(uint64));
>
>
> Won't this mix up column numbers on big-endian systems?

Yes, I believe you're right. I've added the following before the memcpy().

#ifdef WORDS_BIGENDIAN

/*
* Fix byte order on big-endian machines before copying to the array.
*/
isnull_8 = pg_bswap64(isnull_8);
#endif

>
> Subject: [PATCH v9 1/5] Introduce deform_bench test module
>
> For benchmaring tuple deformation.
> ---
>
> Typo: should be benchmarking

Fixed.

> + * firstNonGuaranteedAttr stores the index to info the compact_attrs array for
>
> to info should be "into"?

Also fixed.

I've attached a revised set of patches.

David

Attachment Content-Type Size
v10-0001-Introduce-deform_bench-test-module.patch text/plain 7.3 KB
v10-0002-Add-empty-TupleDescFinalize-function.patch text/plain 29.0 KB
v10-0003-Optimize-tuple-deformation.patch text/plain 60.4 KB
v10-0004-Allow-sibling-call-optimization-in-slot_getsomea.patch text/plain 8.5 KB
v10-0005-Reduce-size-of-CompactAttribute-struct-to-8-byte.patch text/plain 5.5 KB

In response to

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message David Rowley 2026-02-25 00:59:53 Re: More speedups for tuple deformation
Previous Message Gyan Sreejith 2026-02-24 23:55:08 Re: [Proposal] Adding Log File Capability to pg_createsubscriber