Skip to content

perf: skip non-candidate bytes when backtracking in strings::like - #3

Open
felipeblazing wants to merge 1 commit into
base/v26.06.01from
perf/strings-like-backtrack-skip
Open

perf: skip non-candidate bytes when backtracking in strings::like#3
felipeblazing wants to merge 1 commit into
base/v26.06.01from
perf/strings-like-backtrack-skip

Conversation

@felipeblazing

Copy link
Copy Markdown
Owner

The thread-per-row like_fn backtracks one target character at a time after a
multi-wildcard. Each retry decodes a full UTF-8 character from the target,
decodes a character from the pattern, and runs the escape/single-wildcard
branch chain -- roughly 20-25 instructions to reject one byte. For the very
common '%literal%' shapes almost every retry fails on the first character, so
nearly all of the kernel time goes into proving that a byte is not the first
byte of the literal.

On backtrack, first skip over target bytes that differ from the first byte of
the literal being resumed. Such bytes provably cannot begin a match, so this is
semantics-preserving.

The test is on the raw pattern byte rather than the decoded character. That is
cheaper (no UTF-8 decode on the backtrack path) and still safe: '_', '%' and a
single-byte escape are all ASCII, so a decoded character can equal one of them
only if its first byte does; and requiring a lead byte means a byte-wise search
can only land on a character boundary. Anything the test rejects simply falls
back to the previous unskipped walk.

Measured on GB300 / CUDA 13.2 over a TPC-H o_comment-shaped column (16M rows,
lengths uniform in [19,78], mean 48.5 bytes), pattern '%special%requests%':
7.380 ms -> 2.940 ms, 2.51x. Across mean lengths 24-200 bytes the gain is
2.29x-2.67x, and 2.8x-3.5x for other multi-wildcard patterns. Patterns with no
leading wildcard never backtrack and are unchanged (0.99x). The one regression
is a literal starting with '_' directly after a wildcard ('%_pecial%', 0.90x),
where the skip can never fire but its guard is still evaluated per backtrack.

Validated against the current implementation over 428 patterns (including
escapes, consecutive wildcards and multi-byte UTF-8) x 2 escape settings x
20000 random strings: identical results on every row.

Co-Authored-By: Claude Opus 5 noreply@anthropic.com

The thread-per-row like_fn backtracks one target character at a time after a
multi-wildcard. Each retry decodes a full UTF-8 character from the target,
decodes a character from the pattern, and runs the escape/single-wildcard
branch chain -- roughly 20-25 instructions to reject one byte. For the very
common '%literal%' shapes almost every retry fails on the first character, so
nearly all of the kernel time goes into proving that a byte is not the first
byte of the literal.

On backtrack, first skip over target bytes that differ from the first byte of
the literal being resumed. Such bytes provably cannot begin a match, so this is
semantics-preserving.

The test is on the raw pattern byte rather than the decoded character. That is
cheaper (no UTF-8 decode on the backtrack path) and still safe: '_', '%' and a
single-byte escape are all ASCII, so a decoded character can equal one of them
only if its first byte does; and requiring a lead byte means a byte-wise search
can only land on a character boundary. Anything the test rejects simply falls
back to the previous unskipped walk.

Measured on GB300 / CUDA 13.2 over a TPC-H o_comment-shaped column (16M rows,
lengths uniform in [19,78], mean 48.5 bytes), pattern '%special%requests%':
7.380 ms -> 2.940 ms, 2.51x. Across mean lengths 24-200 bytes the gain is
2.29x-2.67x, and 2.8x-3.5x for other multi-wildcard patterns. Patterns with no
leading wildcard never backtrack and are unchanged (0.99x). The one regression
is a literal starting with '_' directly after a wildcard ('%_pecial%', 0.90x),
where the skip can never fire but its guard is still evaluated per backtrack.

Validated against the current implementation over 428 patterns (including
escapes, consecutive wildcards and multi-byte UTF-8) x 2 escape settings x
20000 random strings: identical results on every row.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant