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

From: Michael Forney <mforney_AT_mforney.org>
Date: Wed, 26 Jun 2019 16:28:40 -0700

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 - 01:28:40 CEST

This archive was generated by hypermail 2.3.0 : Thu Jun 27 2019 - 02:36:23 CEST