[PATCH] Add pg_lfind8_nonzero()

Started by cca55074 months ago5 messageshackers
Jump to latest
#1cca5507
cca5507@qq.com

Hi hackers,

I'd like to add pg_lfind8_nonzero() to optimize some code like this:

```
for (i = 0; i < numberOfAttributes; i++)
{
if (isnull[i])
{
hasnull = true;
break;
}
}
```

With pg_lfind8_nonzero(), we can write the code like this:

```
if (likely(numberOfAttributes > 0))
hasnull = pg_lfind8_nonzero((uint8 *) isnull, numberOfAttributes);
```

The pg_lfind8_nonzero() is faster because we can handle 8 bool values at a time.

v1-0001 add the pg_lfind8_nonzero().

v1-0002 use the pg_lfind8_nonzero() in some places.

v1-0003 add a extension "test_patch" only for testing, the test like this:

```
for (i = 0; i < 1000; i++)
{
for (int j = 0; j < natts; j++)
{
if (isnull[j])
{
hasnull = true;
break;
}
}
}
=======================
for (i = 0; i < 1000; i++)
{
if (likely(natts > 0))
hasnull = pg_lfind8_nonzero((uint8 *) isnull, natts);
}
```

create extension test_patch;
# 4 is the natts
select test_head(4);
select test_patch(4);

Test result:
natts: 4 head: 1984ns patch: 2094ns
natts: 8 head: 3196ns patch: 641ns
natts: 16 head: 4589ns patch: 752ns
natts: 32 head: 8036ns patch: 1152ns
natts: 64 head: 19367ns patch: 2455ns
natts: 128 head: 33445ns patch: 4018ns

Looking forward to your comments!

--
Regards,
ChangAo Chen

Attachments:

v1-0001-Add-pg_lfind8_nonzero.patchapplication/octet-stream; charset=utf-8; name=v1-0001-Add-pg_lfind8_nonzero.patchDownload+68-1
v1-0002-Use-pg_lfind8_nonzero.patchapplication/octet-stream; charset=utf-8; name=v1-0002-Use-pg_lfind8_nonzero.patchDownload+11-35
v1-0003-Test-pg_lfind8_nonzero.patch.tmpapplication/octet-stream; charset=utf-8; name=v1-0003-Test-pg_lfind8_nonzero.patch.tmpDownload+102-1
#2Andres Freund
andres@anarazel.de
In reply to: cca5507 (#1)
Re: [PATCH] Add pg_lfind8_nonzero()

Hi,

On 2025-12-14 21:33:00 +0800, cca5507 wrote:

Hi hackers,

I'd like to add pg_lfind8_nonzero() to optimize some code like this:

```
for (i = 0; i < numberOfAttributes; i++)
{
if (isnull[i])
{
hasnull = true;
break;
}
}
```

Is code like this ever actually relevant for performance? In cases where the
compiler can't also optimize the code? Unless it is a legitimate bottleneck,
adding more complicated code to optimize the case doesn't make sense.

create extension test_patch;
# 4 is the natts
select test_head(4);
select test_patch(4);

Test result:
natts: 4 head: 1984ns patch: 2094ns
natts: 8 head: 3196ns patch: 641ns
natts: 16 head: 4589ns patch: 752ns
natts: 32 head: 8036ns patch: 1152ns
natts: 64 head: 19367ns patch: 2455ns
natts: 128 head: 33445ns patch: 4018ns

Looking forward to your comments!

The benchmark really should show performance benefits in at least somewhat
realistic cases (i.e. real users of the functions, even if the workload is a
bit more extreme than it'd be most of the time).

Greetings,

Andres

#3cca5507
cca5507@qq.com
In reply to: Andres Freund (#2)
Re: [PATCH] Add pg_lfind8_nonzero()

Hi,

Thank you for your reply!

Is code like this ever actually relevant for performance? In cases where the
compiler can't also optimize the code? Unless it is a legitimate bottleneck,
adding more complicated code to optimize the case doesn't make sense.

I just think the patch isn't that complicated.

The benchmark really should show performance benefits in at least somewhat
realistic cases (i.e. real users of the functions, even if the workload is a
bit more extreme than it'd be most of the time).

Yeah, this makes sense to me. Maybe I need to think more on it.

--
Regards,
ChangAo Chen

#4Peter Eisentraut
peter_e@gmx.net
In reply to: cca5507 (#1)
Re: [PATCH] Add pg_lfind8_nonzero()

On 14.12.25 14:33, cca5507 wrote:

With pg_lfind8_nonzero(), we can write the code like this:

```
if (likely(numberOfAttributes > 0))
hasnull = pg_lfind8_nonzero((uint8 *) isnull, numberOfAttributes);
```

The pg_lfind8_nonzero() is faster because we can handle 8 bool values at a time.

Maybe you could try popcount for this?

hasnull = (pg_popcount((char *) isnull, numberOfAttributes) > 0);

#5cca5507
cca5507@qq.com
In reply to: Peter Eisentraut (#4)
Re: [PATCH] Add pg_lfind8_nonzero()

Hi,

Maybe you could try popcount for this?

     hasnull = (pg_popcount((char *) isnull, numberOfAttributes) > 0);

It seems that pg_popcount() cannot early return when we find a nonzero value, so I don't
think it's a good choice for this case.

--
Regards,
ChangAo Chen