Skip to content

wc: Assume long lines initially and find EOL with rawmemchr() - #351

Open
roman-zilka wants to merge 1 commit into
coreutils:masterfrom
roman-zilka:wc-long_lines
Open

roman-zilka wants to merge 1 commit into
coreutils:masterfrom
roman-zilka:wc-long_lines

Conversation

@roman-zilka

Copy link
Copy Markdown

Start processing input by assuming its lines are long (>= 15 characters) and use rawmemchr() instead of checking individual bytes to find EOLs. The average line length in the distribution of linux-7.2.4 is 36 characters. Moving byte-by-byte is grossly suboptimal for long lines.

Confirmed experimentally that the 15-character threshold is optimal.

Start processing input by assuming its lines are long (>= 15 characters)
and use rawmemchr() instead of checking individual bytes to find EOLs.
The average line length in the distribution of linux-7.2.4 is 36
characters. Moving byte-by-byte is grossly suboptimal for long lines.

Confirmed experimentally that the 15-character threshold is optimal:
github.com/coreutils/pull/347#issuecomment-5653011937
@roman-zilka

roman-zilka commented Sep 13, 2026

Copy link
Copy Markdown
Author

Also:

$ A=$(for i in $(find /etc/ -type f); do file "$i"|grep ': ASCII text$' >/dev/null && cat "$i"; done | wc -l)
$ B=$(for i in $(find /etc/ -type f); do file "$i"|grep ': ASCII text$' >/dev/null && cat "$i"; done | wc -c)
$ echo $A $B $(( (B-A) / A ))
23603 744436 30

roman-zilka added a commit to roman-zilka/coreutils that referenced this pull request Sep 13, 2026
Estimate the length of lines in input and choose a method of finding EOLs
appropriately to increase performance: memchr() for long lines, manual
byte-wise search for short lines. Long-short threshold = 15,
experimentally:
github.com/coreutils/pull/347#issuecomment-5653011937
Initial guess = long lines, based on Linux sources and /etc:
coreutils#351
@roman-zilka

roman-zilka commented Sep 13, 2026

Copy link
Copy Markdown
Author

Well, now I built coreutils with a simple configure && make and ran wc with and without this modification against linux-6.18.51 sources. long_lines = false by default came up faster. Beats me. Average line length = 36.

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.

1 participant