summaryrefslogtreecommitdiff
path: root/usr.bin/yes
diff options
context:
space:
mode:
authorPietro Cerutti <gahr@FreeBSD.org>2017-06-13 12:35:01 +0000
committerPietro Cerutti <gahr@FreeBSD.org>2017-06-13 12:35:01 +0000
commitdadfd1ed33e4ca779998ddeca7d5b0bb30098543 (patch)
tree5cb266a031353f182a1d8ec174ed824cc3592353 /usr.bin/yes
parent7bf5720a3f84bf181bb5d3af8362a066d3087d36 (diff)
downloadsrc-test-dadfd1ed33e4ca779998ddeca7d5b0bb30098543.tar.gz
src-test-dadfd1ed33e4ca779998ddeca7d5b0bb30098543.zip
Improve yes' throughput
On my system, this brings up the throughput from ~20 to ~600 MiB/s. Inspired by: https://www.reddit.com/r/unix/comments/6gxduc/how_is_gnu_yes_so_fast/ Reviewed by: cognet Approved by: cognet
Notes
Notes: svn path=/head/; revision=319897
Diffstat (limited to 'usr.bin/yes')
-rw-r--r--usr.bin/yes/yes.c32
1 files changed, 27 insertions, 5 deletions
diff --git a/usr.bin/yes/yes.c b/usr.bin/yes/yes.c
index 8febdded89865..322668b87069b 100644
--- a/usr.bin/yes/yes.c
+++ b/usr.bin/yes/yes.c
@@ -44,20 +44,42 @@ static const char rcsid[] = "$FreeBSD$";
#include <capsicum_helpers.h>
#include <err.h>
#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
int
main(int argc, char **argv)
{
+ char buf[8192];
+ char y[2] = { 'y', '\n' };
+ char * exp = y;
+ size_t buflen = 0;
+ size_t explen = sizeof(y);
if (caph_limit_stdio() < 0 || (cap_enter() < 0 && errno != ENOSYS))
err(1, "capsicum");
if (argc > 1)
- while (puts(argv[1]) != EOF)
- ;
- else
- while (puts("y") != EOF)
- ;
+ {
+ exp = argv[1];
+ explen = strlen(exp) + 1;
+ exp[explen - 1] = '\n';
+ }
+
+ if (explen <= sizeof(buf))
+ {
+ while (buflen < sizeof(buf) - explen)
+ {
+ memcpy(buf + buflen, exp, explen);
+ buflen += explen;
+ }
+ exp = buf;
+ explen = buflen;
+ }
+
+ while (write(STDOUT_FILENO, exp, explen) > 0)
+ ;
+
err(1, "stdout");
/*NOTREACHED*/
}