grep: avoid multi-character case folds#54
Conversation
Merging this PR will improve performance by 22.08%
|
| Benchmark | BASE |
HEAD |
Efficiency | |
|---|---|---|---|---|
| ⚡ | recursive_no_binary |
29.3 ms | 22.3 ms | +31.07% |
| ⚡ | regex_no_match |
29.6 ms | 22.7 ms | +30.59% |
| ⚡ | context |
32.1 ms | 25.1 ms | +27.58% |
| ⚡ | only_matching |
54.9 ms | 46.8 ms | +17.35% |
| ⚡ | filename_lineno_color |
55 ms | 46.9 ms | +17.32% |
| ⚡ | invert_match |
75 ms | 68.1 ms | +10.11% |
Tip
Curious why this is faster? Comment @codspeedbot explain why this is faster on this PR, or directly use the CodSpeed MCP with your agent.
Comparing wondr-wclabs:codex/simple-case-folding (7bae963) with main (35b6dc6)
Footnotes
-
17 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports. ↩
|
suggestion: Could we add a control test for a non-ASCII one-to-one case fold, such as The current tests verify that multi-character folds like |
|
@copilot resolve the merge conflicts in this pull request |
Fixes #32.
This changes the ignore-case compile path to use Oniguruma's per-regex
onig_new_deluxeAPI with the default case-fold flags minusINTERNAL_ONIGENC_CASE_FOLD_MULTI_CHAR.The important distinction is that this is not only an output formatting issue. With Oniguruma's default full-fold behavior, one regex atom can consume multiple input characters:
[[:alpha:]]can matchstas a single match, andßcan matchSS. That changes-ooutput, match counts, and cursor advancement. GNU grep avoids those multi-character fold expansions forgrep -i, so the matcher needs to stay on simple one-to-one folds even before broader locale support exists.I avoided
ONIG_OPTION_IGNORECASE_IS_ASCIIbecause that would be a broader behavioral change: it would discard non-ASCII simple folds too, while the incompatibility here is specifically the multi-character fold expansion. I also avoidedonig_set_default_case_fold_flagbecause it is process-global; using compile-timeOnigCompileInfokeeps the change local to each compiled regex and avoids races between different pattern compilations.The small raw wrapper mirrors the existing
onig::Regexshape where relevant: it serializes regex construction with a mutex, keeps the sameSend/Syncownership model for immutable compiled regexes, reusesonig::Region's transparent raw representation, and formats errors through Oniguruma's own error-message API.Validation:
cargo fmt --all -- --checkcargo testcargo clippy --all-targets --workspace -puu_grep -- -D warningsgit diff --checkprintf 'st\nss\nffi\n' | cargo run --quiet -- -o -i '[[:alpha:]]'now emits one character per lineprintf 'SS\n' | cargo run --quiet -- -o -i 'ß'exits 1 with no output