[PATCH] py3: make ui.write() call fout.flush() per line if fout is a tty or pager
Yuya Nishihara
yuya at tcha.org
Mon Jun 8 13:35:14 UTC 2020
On Mon, 8 Jun 2020 14:59:40 +0200, Joerg Sonnenberger wrote:
> On Mon, Jun 08, 2020 at 09:11:48PM +0900, Yuya Nishihara wrote:
> > On Sun, 7 Jun 2020 22:09:58 +0200, Joerg Sonnenberger wrote:
> > > On Sun, Jun 07, 2020 at 08:55:03PM +0900, Yuya Nishihara wrote:
> > > > With my testing, inserting flush() automatically showed a better result than
> > > > using unbuffered io, so this patch implements (b). Since ui._isatty() call
> > > > isn't cheap, the result is cached. I also made ui.write() not scan the
> > > > entire string because it's unlikely that a string including '\n' doesn't
> > > > end with '\n'.
> > >
> > > I'm not sure about the last part. Checking for \n first at the end makes
> > > a lot of sense to me, but I don't think we should micro-optimize away
> > > the scan here. Does it really make that much a difference?
> >
> > I submitted this patch without testing that, but actually msg.rfind(b'\n')
> > is slightly slower than msg.endswith(b'\n').
> >
> > % HGRCPATH=/dev/null python3 ./hg --cwd ~/mirrors/mozilla-central \
> > --time --pager no status --all
> >
> > msg.endswith(b'\n')
> > time: real 12.930 secs (user 11.580+0.000 sys 1.350+0.000)
> > time: real 12.800 secs (user 11.450+0.000 sys 1.350+0.000)
> > time: real 12.790 secs (user 11.360+0.000 sys 1.420+0.000)
> >
> > msg.rfind(b'\n')
> > time: real 13.470 secs (user 11.790+0.000 sys 1.650+0.000)
> > time: real 14.520 secs (user 12.550+0.000 sys 1.760+0.000)
> > time: real 13.440 secs (user 11.640+0.000 sys 1.770+0.000)
> >
> > And dest.flush() will have to be inserted inbetween write()s.
> >
> > p = msg.rfind(b'\n')
> > dest.write(msg[:p + 1])
> > dest.flush()
> > dest.write(msg[p + 1:])
> >
> > Since ui isn't an IO object, I think checking the common case should be
> > good.
>
> That's not what I meant. I was thinking along the lines of:
>
> dest.write(msg)
> if msg.endswith(b'\n') or b'\n' in msg:
> dest.flush()
>
> I don't see a reason for flushing in the middle as long as we flush at
> all.
Well, that's the line-buffered stdio behavior.
% python -c 'import sys, time; sys.stdout.write("foo\nbar"); time.sleep(1)'
More information about the Mercurial-devel
mailing list