Skip to content

Conversation

@viirya
Copy link
Member

@viirya viirya commented Dec 29, 2025

Which issue does this PR close?

  • Closes #.

Rationale for this change

What changes are included in this PR?

Replace .chars().skip().collect::<String>() with zero-copy string slicing using char_indices() to find the byte offset, then slice with &value[byte_offset..].

This eliminates unnecessary String allocation per row when a start position is specified.

Changes:

  • Use char_indices().nth() to find byte offset for start position (1-based)
  • Use string slicing &value[byte_offset..] instead of collecting chars
  • Added benchmark to measure performance improvements

Optimization:

  • Before: Allocated new String via .collect() for each row with start position
  • After: Uses zero-copy string slice

Benchmark results:

  • size=1024, str_len=32: 96.361 µs -> 41.458 µs (57.0% faster, 2.3x speedup)
  • size=1024, str_len=128: 210.16 µs -> 56.064 µs (73.3% faster, 3.7x speedup)
  • size=4096, str_len=32: 376.90 µs -> 162.98 µs (56.8% faster, 2.3x speedup)
  • size=4096, str_len=128: 855.68 µs -> 263.61 µs (69.2% faster, 3.2x speedup)

The optimization shows greater improvements for longer strings (up to 73% faster) since string slicing is O(1) regardless of length, while the previous approach had allocation costs that grew with string length.

Are these changes tested?

Are there any user-facing changes?

@github-actions github-actions bot added the functions Changes to functions implementation label Dec 29, 2025
…ition is provided

Replace `.chars().skip().collect::<String>()` with zero-copy string slicing
using `char_indices()` to find the byte offset, then slice with `&value[byte_offset..]`.

This eliminates unnecessary String allocation per row when a start position
is specified.

Changes:
- Use char_indices().nth() to find byte offset for start position (1-based)
- Use string slicing &value[byte_offset..] instead of collecting chars
- Added benchmark to measure performance improvements

Optimization:
- Before: Allocated new String via .collect() for each row with start position
- After: Uses zero-copy string slice

Benchmark results:
- size=1024, str_len=32:  96.361 µs -> 41.458 µs (57.0% faster, 2.3x speedup)
- size=1024, str_len=128: 210.16 µs -> 56.064 µs (73.3% faster, 3.7x speedup)
- size=4096, str_len=32:  376.90 µs -> 162.98 µs (56.8% faster, 2.3x speedup)
- size=4096, str_len=128: 855.68 µs -> 263.61 µs (69.2% faster, 3.2x speedup)

The optimization shows greater improvements for longer strings (up to 73% faster)
since string slicing is O(1) regardless of length, while the previous approach
had allocation costs that grew with string length.
@viirya viirya force-pushed the regexp_count_optimize branch from 8f465d6 to dbdc19c Compare December 29, 2025 19:43
@viirya viirya requested a review from andygrove December 30, 2025 00:36
.unwrap_or(value.len());

// Use string slicing instead of collecting chars into a new String
let find_slice = &value[byte_offset..];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @viirya a quick question as this PR refers to the string by offset directly, would be that UTF compliant?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. char_indices is the same as chars working on Unicode Scalar Value.

Copy link
Contributor

@comphead comphead left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @viirya again 💪

@viirya viirya added this pull request to the merge queue Dec 30, 2025
@viirya
Copy link
Member Author

viirya commented Dec 30, 2025

Thanks @comphead

Merged via the queue into apache:main with commit 56a2be1 Dec 30, 2025
31 checks passed
@viirya viirya deleted the regexp_count_optimize branch December 30, 2025 21:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

functions Changes to functions implementation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants