wc(1): Extend non-controversial optimizations to '-c' mode
wc(1)'s slow path for counting words or multibyte characters requires conversion of the 8-bit input stream to wide characters. However, a faster path can be used for counting only lines ('-l' -- newlines have the same representation in all supported encodings) or bytes ('-c'). The existing line count optimization was not used if the input was the implicit stdin. Additionally, it wasn't used if only byte counting was requested. This change expands the fast path to both of these scenarios. Expanding the buffer size from 64 kB helps reduce the number of read(2) calls needed, but exactly what impact that change has and what size to expand the buffer to are still under discussion. PR: 224160 Tested by: wosch (earlier version) Sponsored by: Dell EMC Isilon
This commit is contained in:
parent
219afc4fe2
commit
de1430411d
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=326736
101
usr.bin/wc/wc.c
101
usr.bin/wc/wc.c
@ -206,30 +206,30 @@ cnt(const char *file)
|
|||||||
linect = wordct = charct = llct = tmpll = 0;
|
linect = wordct = charct = llct = tmpll = 0;
|
||||||
if (file == NULL)
|
if (file == NULL)
|
||||||
fd = STDIN_FILENO;
|
fd = STDIN_FILENO;
|
||||||
else {
|
else if ((fd = open(file, O_RDONLY, 0)) < 0) {
|
||||||
if ((fd = open(file, O_RDONLY, 0)) < 0) {
|
xo_warn("%s: open", file);
|
||||||
xo_warn("%s: open", file);
|
return (1);
|
||||||
return (1);
|
}
|
||||||
}
|
if (doword || (domulti && MB_CUR_MAX != 1))
|
||||||
if (doword || (domulti && MB_CUR_MAX != 1))
|
goto word;
|
||||||
goto word;
|
/*
|
||||||
/*
|
* Line counting is split out because it's a lot faster to get
|
||||||
* Line counting is split out because it's a lot faster to get
|
* lines than to get words, since the word count requires some
|
||||||
* lines than to get words, since the word count requires some
|
* logic.
|
||||||
* logic.
|
*/
|
||||||
*/
|
if (doline || dochar) {
|
||||||
if (doline) {
|
while ((len = read(fd, buf, MAXBSIZE))) {
|
||||||
while ((len = read(fd, buf, MAXBSIZE))) {
|
if (len == -1) {
|
||||||
if (len == -1) {
|
xo_warn("%s: read", file);
|
||||||
xo_warn("%s: read", file);
|
(void)close(fd);
|
||||||
(void)close(fd);
|
return (1);
|
||||||
return (1);
|
}
|
||||||
}
|
if (siginfo) {
|
||||||
if (siginfo) {
|
show_cnt(file, linect, wordct, charct,
|
||||||
show_cnt(file, linect, wordct, charct,
|
llct);
|
||||||
llct);
|
}
|
||||||
}
|
charct += len;
|
||||||
charct += len;
|
if (doline) {
|
||||||
for (p = buf; len--; ++p)
|
for (p = buf; len--; ++p)
|
||||||
if (*p == '\n') {
|
if (*p == '\n') {
|
||||||
if (tmpll > llct)
|
if (tmpll > llct)
|
||||||
@ -239,37 +239,38 @@ cnt(const char *file)
|
|||||||
} else
|
} else
|
||||||
tmpll++;
|
tmpll++;
|
||||||
}
|
}
|
||||||
reset_siginfo();
|
}
|
||||||
|
reset_siginfo();
|
||||||
|
if (doline)
|
||||||
tlinect += linect;
|
tlinect += linect;
|
||||||
if (dochar)
|
if (dochar)
|
||||||
tcharct += charct;
|
tcharct += charct;
|
||||||
if (dolongline) {
|
if (dolongline) {
|
||||||
if (llct > tlongline)
|
if (llct > tlongline)
|
||||||
tlongline = llct;
|
tlongline = llct;
|
||||||
}
|
}
|
||||||
|
show_cnt(file, linect, wordct, charct, llct);
|
||||||
|
(void)close(fd);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* If all we need is the number of characters and it's a
|
||||||
|
* regular file, just stat the puppy.
|
||||||
|
*/
|
||||||
|
if (dochar || domulti) {
|
||||||
|
if (fstat(fd, &sb)) {
|
||||||
|
xo_warn("%s: fstat", file);
|
||||||
|
(void)close(fd);
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
|
if (S_ISREG(sb.st_mode)) {
|
||||||
|
reset_siginfo();
|
||||||
|
charct = sb.st_size;
|
||||||
show_cnt(file, linect, wordct, charct, llct);
|
show_cnt(file, linect, wordct, charct, llct);
|
||||||
|
tcharct += charct;
|
||||||
(void)close(fd);
|
(void)close(fd);
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
* If all we need is the number of characters and it's a
|
|
||||||
* regular file, just stat the puppy.
|
|
||||||
*/
|
|
||||||
if (dochar || domulti) {
|
|
||||||
if (fstat(fd, &sb)) {
|
|
||||||
xo_warn("%s: fstat", file);
|
|
||||||
(void)close(fd);
|
|
||||||
return (1);
|
|
||||||
}
|
|
||||||
if (S_ISREG(sb.st_mode)) {
|
|
||||||
reset_siginfo();
|
|
||||||
charct = sb.st_size;
|
|
||||||
show_cnt(file, linect, wordct, charct, llct);
|
|
||||||
tcharct += charct;
|
|
||||||
(void)close(fd);
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Do it the hard way... */
|
/* Do it the hard way... */
|
||||||
|
Loading…
Reference in New Issue
Block a user