yongster opened a new pull request, #11137:
URL: https://github.com/apache/arrow-rs/pull/11137

   # Which issue does this PR close?
   
   - Closes #11084.
   
   # Rationale for this change
   
   Array/array `LIKE` / `ILIKE` / `NLIKE` / `NILIKE` go through 
`binary_predicate`, which only reused the immediately previous pattern. Two or 
more complex (Regex-backed) patterns that alternate — or any low-cardinality 
pattern column that is not grouped — therefore re-ran `regex_like` + 
`RegexBuilder::build` on almost every row. Performance then depended on row 
order even when the logical workload had only a few distinct patterns.
   
   Simple patterns (`x%`, `%x`, `%x%`, equality) do not compile a Regex and 
were already cheap. The scalar path already builds one `Predicate` and is 
unchanged.
   
   # What changes are included in this PR?
   
   - Keep the existing previous-pattern fast path so consecutive duplicates do 
not pay an extra lookup.
   - Add a bounded cache (8 entries) of compiled **Regex** predicates, keyed by 
borrowed `&str` from the pattern array.
   - Once the cache is full, additional patterns are evaluated without being 
retained, so a unique pattern per row cannot accumulate an unbounded number of 
`Regex` values.
   - Keep `previous` even for a pattern that was not inserted into the cache, 
so a consecutive run of an uncached pattern does not recompile every row.
   - Prefix/suffix/contains/equality predicates are not cached; rebuilding them 
is cheaper than cache bookkeeping.
   - Tests for alternating complex patterns across LIKE/NLIKE/ILIKE/NILIKE 
(Utf8 / LargeUtf8 / Utf8View / Dictionary), mixed nulls, and more distinct 
patterns than the cache cap.
   - Criterion benches for consecutive complex, alternating complex, simple 
alternating, and all-unique complex array/array LIKE.
   
   # Are these changes tested?
   
   Yes. `cargo test -p arrow-string --lib like`: 63 passed.
   
   Independent remeasurement of the public `like` / `ilike` APIs on arm64 
macOS, 1,024 rows of `"xxxxxxxx"`:
   
   | Case | Before | After |
   |---|---:|---:|
   | LIKE, one complex pattern, consecutive | 52.4 µs | 40.0 µs |
   | LIKE, two complex patterns, alternating | 21.18 ms | 62.1 µs (~341×) |
   | ILIKE, two complex patterns, alternating | 21.64 ms | 65.6 µs (~330×) |
   | LIKE, two simple patterns (`x%` / `%x`), alternating | 13.2 µs | 15.9 µs |
   | LIKE, 1,024 unique complex patterns | 18.86 ms | 18.54 ms |
   
   Criterion (`cargo bench -p arrow --features test_utils --bench 
comparison_kernels -- "like_utf8 array"`) after the change:
   
   | Bench | time |
   |---|---:|
   | `like_utf8 array complex consecutive` | 38.4 µs |
   | `like_utf8 array complex alternating` | 58.8 µs |
   | `ilike_utf8 array complex alternating` | 59.6 µs |
   | `like_utf8 array simple alternating` | 15.9 µs |
   | `like_utf8 array complex unique` | 18.6 ms |
   
   `cargo fmt --all -- --check` and `cargo clippy -p arrow-string --lib 
--all-targets -- -D warnings` pass.
   
   # Are there any user-facing changes?
   
   No. Logical results are unchanged; this is an internal reuse policy for 
compiled Regex predicates.
   
   AI assistance: implementation and tests were drafted with AI and then 
reviewed, corrected (Regex-only cache so simple patterns do not regress), and 
remeasured locally.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to