Re: [hackers] [sbase][PATCH] Minor optimizations for 'yes'

From: aidanwillie0317 <aidanwillie0317_AT_protonmail.com>
Date: Thu, 27 Jun 2019 08:57:28 +0000

> What about /dev/zero?
I really overengineered this benchmark, and I completely forgot about that.

> In fact, since yes(1) is a non-standard utility, I wonder if we should
> even bother supporting multiple arguments. It looks like some BSD
> implementations only repeat the first argument.
>
> So, we could make this as simple as
>
> s = argc > 1 ? argv[1] : "y";
>
> for (;;)
> puts(s);
>
Or, even simpler:
---
 yes.c | 10 +++-------
 1 file changed, 3 insertions(+), 7 deletions(-)
diff --git a/yes.c b/yes.c
index dd97ea6..5f3b2e1 100644
--- a/yes.c
+++ b/yes.c
_AT_@ -6,14 +6,10 @@
 int
 main(int argc, char *argv[])
 {
-       char **p;
+       char *p = argv[1] ? argv[1] : "y";
-       argv0 = *argv, argv0 ? (argc--, argv++) : (void *)0;
-
-       for (p = argv; ; p = (*p && *(p + 1)) ? p + 1 : argv) {
-               fputs(*p ? *p : "y", stdout);
-               putchar((!*p || !*(p + 1)) ? '\n' : ' ');
-       }
+       for (;;)
+               puts(p);
        return 1; /* not reached */
 }
--
2.21.0
‐‐‐‐‐‐‐ Original Message ‐‐‐‐‐‐‐
On Wednesday, June 26, 2019 7:28 PM, Michael Forney <mforney_AT_mforney.org> wrote:
> On 2019-06-26, aidanwillie0317 aidanwillie0317_AT_protonmail.com wrote:
>
> > On Wednesday, June 26, 2019 4:04:50 AM EDT you wrote:
> >
> > > What's the motivation for this? Are you running into performance
> > > issues with yes(1), or is this just for fun to increase the throughput
> > > for some benchmark?
> > > One of yes(1)'s uses (besides the intended use of making interactive
> > > programs
> > > work noninteractively) is to generate a high volume stream of data, as
> > > /dev/
> > > urandom will only go up around 10MiB/s on most devices. I was doing some
> > > testing for a personal program to see how well it could handle an influx of
> > > data, and I noticed that the sbase yes is much slower than the GNU and
> > > FreeBSD
> > > implementations. So, I patched the sbase one quickly and got it to run
> > > faster
> > > than many implementations (GNU yes being a major exception, running at
> > > ~4GiB/s
> > > on my machine).
>
> What about /dev/zero? Or do you need ASCII data? I don't think yes(1)
> is the right tool for the job. As you said, it is meant for
> auto-responding to prompts.
>
> > As you said before, the code is hard to follow, so I didn't mess with that
> > part that much. However, in retrospect, the code can be simplfied to this:
> > for (p = argv; ; p = *(p + 1) ? p + 1 : argv) {
> > fputs(p, stdout);
> > putchar(!(p + 1) ? '\n' : ' ');}
>
> Thanks, that looks better. I'm thinking this might be even clearer to
> use an index instead of advancing a pointer:
>
> i = 0;
> for (;;) {
> fputs(argv[i], stdout);
> i = (i + 1) % argc;
> putchar(i ? '\n' : ' ');
> }
>
> In fact, since yes(1) is a non-standard utility, I wonder if we should
> even bother supporting multiple arguments. It looks like some BSD
> implementations only repeat the first argument.
>
> So, we could make this as simple as
>
> s = argc > 1 ? argv[1] : "y";
>
>     for (;;)
>     	puts(s);
>
>
> > > I think I'd prefer
> > > for (;;)
> > > puts("y");
> > > here.
> > > Originally, I had a puts(3) call there, but this decreased the performance
> > > from the unpatched sbase, so I changed it to some fputc calls. Calling
> > > write(2) didn't help either. I researched why and it's due to some
> > > buffering,
> > > but adding buffering would overcomplicate the code.
>
> I think the major slowdown here is from locking and unlocking the file
> for every loop iteration. Using putchar_unlocked will be much faster
> than a plain putchar. But anyway, I think we should stick to puts(3)
> for simplicity.
Received on Thu Jun 27 2019 - 10:57:28 CEST

This archive was generated by hypermail 2.3.0 : Thu Jun 27 2019 - 11:00:24 CEST