Skip to content

tac: use anchored regex search to avoid quadratic scan - #15911

Open
fixfon wants to merge 1 commit into
uutils:mainfrom
fixfon:fix/15775-tac-regex-quadratic
Open

fixfon wants to merge 1 commit into
uutils:mainfrom
fixfon:fix/15775-tac-regex-quadratic

Conversation

@fixfon

@fixfon fixfon commented Oct 27, 2026 •

Copy link
Copy Markdown
Contributor

Closes #15775

tac -r looked for the separator with an unanchored Regex::find_at and then threw the match away unless it started at the current position. On a long record with no separator, each position scanned to the end of the record, so the run time grew quadratically.

buffer_tac_regex now uses regex_automata::meta::Regex and runs an anchored search at each position. The regex is built with the same syntax settings as before. TacError::InvalidRegex holds the new build error, and a small helper in error.rs keeps the error messages unchanged. regex-automata was already in the dependency tree through regex.

Tests: test_regex_long_record_is_not_quadratic times out on the old code and passes now; test_invalid_regex_error_messages pins the existing error messages.

Run locally: cargo fmt --check -p uu_tac and cargo test --locked --offline --features tac --no-default-features test_tac (35 passed). Tested on macOS (arm64).

@codspeed

codspeed Bot commented Oct 27, 2026 •

Copy link
Copy Markdown

Merging this PR will degrade performance by 9.25%

2 warnings, 1 note

⚠️ 122 benchmarks are dominated by system calls

System calls cannot be simulated consistently and are left out of the measure. The reported value understates the real cost. Switch to the Walltime instrument to measure them.

Learn more about system calls

See affected benchmarks

⚠️ Base and head ran on different runner types

Some benchmarks with significant performance changes were compared across different runner types, so the changes might not come from the code. Run base and head on the same runner type, or use CodSpeed Macro Runners for more stable results.

Learn more about Macro Runners

Open the report in CodSpeed to investigate

ℹ️ 1 benchmark has no flamegraph

The flamegraph wasn't generated: most of the time was spent in runtime internals, which would leave nothing useful to analyze.

See affected benchmarks

⚡ 1 improved benchmark
❌ 3 regressed benchmarks
✅ 397 untouched benchmarks
⏩ 70 skipped benchmarks1

Warning

Please fix the performance issues or acknowledge them on CodSpeed.

Performance Changes

Mode Benchmark BASE HEAD Efficiency
❌ Memory cp_recursive_deep_tree[(120, 4)] 532.6 KB 699.2 KB -23.82%
❌ CPU Simulation ls_recursive_wide_tree[(10000, 1000)] 66.3 ms 72.9 ms -9.05%
❌ Memory du_deep_tree[(100, 3)] 76.5 KB 82.4 KB -7.14%
⚡ CPU Simulation du_deep_tree[(100, 3)] 1.8 ms 1.7 ms +5.43%

Tip

Investigate this regression by commenting @codspeedbot fix this regression on this PR, or directly use the CodSpeed MCP with your agent.


Comparing fixfon:fix/15775-tac-regex-quadratic (03dec80) with main (1542121)2

Open in CodSpeed

Footnotes

  1. 70 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. ↩

  2. No successful run was found on main (32b2d60) during the generation of this report, so 1542121 was used instead as the comparison base. There might be some changes unrelated to this pull request in this report. ↩

@xtqqczze

This comment was marked as resolved.

@fixfon
fixfon force-pushed the fix/15775-tac-regex-quadratic branch from b15d079 to 6bc87cc Compare October 27, 2026 17:40
@fixfon

fixfon commented Oct 27, 2026

Copy link
Copy Markdown
Contributor Author

Squashed into one commit and removed the issue reference from the message.

@fixfon
fixfon force-pushed the fix/15775-tac-regex-quadratic branch from 6bc87cc to 03dec80 Compare October 28, 2026 21:55

This branch has not been deployed

No deployments
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.

tac: --regex is quadratic in record length (unanchored search)

2 participants