Skip to content

perf(nl): optimize line numbering by using itoa and direct writing#10757

Merged
ChrisDryden merged 3 commits intouutils:mainfrom
CrazyRoka:optimize-nl-formatting
Feb 6, 2026
Merged

perf(nl): optimize line numbering by using itoa and direct writing#10757
ChrisDryden merged 3 commits intouutils:mainfrom
CrazyRoka:optimize-nl-formatting

Conversation

@CrazyRoka
Copy link
Contributor

This PR optimizes the nl command's performance by refactoring how line numbers are formatted and written. Previously, the code used the format! macro for every line, which involves heap allocations and runtime parsing of format strings.

By integrating the itoa crate and writing directly to the output BufWriter, we significantly reduce the overhead per line.

@github-actions
Copy link

github-actions bot commented Feb 5, 2026

GNU testsuite comparison:

Congrats! The gnu test tests/basenc/bounded-memory is now passing!

@codspeed-hq
Copy link

codspeed-hq bot commented Feb 5, 2026

Merging this PR will improve performance by ×2.2

⚡ 2 improved benchmarks
✅ 282 untouched benchmarks
⏩ 38 skipped benchmarks1

Performance Changes

Mode Benchmark BASE HEAD Efficiency
Simulation nl_large_file[10] 58.8 ms 26.9 ms ×2.2
Simulation nl_many_lines[100000] 46.1 ms 20.8 ms ×2.2

Comparing CrazyRoka:optimize-nl-formatting (bccfda0) with main (25a43c6)

Open in CodSpeed

Footnotes

  1. 38 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.

@CrazyRoka CrazyRoka marked this pull request as ready for review February 5, 2026 23:14
@ChrisDryden
Copy link
Collaborator

Some of the test failures were because of a broken main, rebasing it

@github-actions
Copy link

github-actions bot commented Feb 6, 2026

GNU testsuite comparison:

Skipping an intermittent issue tests/misc/usage_vs_getopt (passes in this run but fails in the 'main' branch)
Skipping an intermittent issue tests/shuf/shuf-reservoir (passes in this run but fails in the 'main' branch)
Skipping an intermittent issue tests/sort/sort-stale-thread-mem (passes in this run but fails in the 'main' branch)

}
Self::RightZero if number < 0 => {
writer.write_all(b"-")?;
let num = buffer.format(number.abs());
Copy link
Collaborator

Choose a reason for hiding this comment

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

Can you used unsigned_abs? I think this can cause a panic

Copy link
Collaborator

Choose a reason for hiding this comment

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

Actually this is unrelated to the original change and was already there lgtm

@ChrisDryden ChrisDryden merged commit ffe2b0b into uutils:main Feb 6, 2026
96 of 97 checks passed
@ChrisDryden
Copy link
Collaborator

Thanks!

@CrazyRoka CrazyRoka deleted the optimize-nl-formatting branch February 7, 2026 16:23
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.

2 participants