Zsh Mailing List Archive
Messages sorted by:
Reverse Date,
Date,
Thread,
Author
Re: Why sourcing a file is not faster than doing a loop with eval, zle -N
- X-seq: zsh-workers 41321
- From: Peter Stephenson <p.w.stephenson@xxxxxxxxxxxx>
- To: Zsh hackers list <zsh-workers@xxxxxxx>
- Subject: Re: Why sourcing a file is not faster than doing a loop with eval, zle -N
- Date: Mon, 19 Jun 2017 20:28:35 +0100
- Dkim-signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ntlworld.com; s=meg.feb2017; t=1497900515; bh=92RHw2uXq3kOAD5Vd8nTTXE6NSwCPGHuLDO1OFIqJQA=; h=Date:From:To:Subject:In-Reply-To:References; b=N+UqOSNsQNgb9nQtnYu6aRW926VNMEVMM5puOBLao4AVnW44kNHq1hbMPHtl2/h8F aI/Nqx3VelGPVLGAusKEQrc9lJi1tXn5lT4pNJ5251XvgHirgsdB1lMm0twWl2/MnU bjjHrLjBZ3e6UYsFk8L/BLt8o9B4i+TD5GVI8B1tVJun3Ixd/64tBwtk4V7Z/efVaj 1AAt/t+5KQchbZW/ReY3tDcMtun8+ODQVhqPI4NjEx5nivqGx7B1SJOyVvPT43xgjH D4/9KJXpCSO/csJjMQrgvth5rP58lxyMCF1/n72QmoDdYWJyDvscaPstS0CvM4MYVD A73G0CcBQEU3w==
- In-reply-to: <20170619161601.GB9294@chaz.gmail.com>
- List-help: <mailto:zsh-workers-help@zsh.org>
- List-id: Zsh Workers List <zsh-workers.zsh.org>
- List-post: <mailto:zsh-workers@zsh.org>
- Mailing-list: contact zsh-workers-help@xxxxxxx; run by ezmlm
- References: <etPan.594513a8.516100cd.10b2e__10513.1716504276$1497699329$gmane$org@zdharma.org> <20170619122413.GA9294@chaz.gmail.com> <170619083116.ZM17323__41722.0601499595$1497886320$gmane$org@torch.brasslantern.com> <20170619161601.GB9294@chaz.gmail.com>
On Mon, 19 Jun 2017 17:16:01 +0100
Stephane Chazelas <stephane.chazelas@xxxxxxxxx> wrote:
> That defeats a benefit of stdio saving read() systems calls by
> reading in chunk if we end up doing one system call per byte
> anyway.
Yes, if it's line buffered we should ideally only be unblocking
interrupts once around reading the line, which will dominate the
timing.
How about something like this? As far as I can tell, fgets is designed
from the ground up as Gets Done Properly, so if you have it on your
system it will work correctly. I can't think of a case where this
wouldn't do the right thing --- fgets will read at most one line and if
it does we were going to get the big STDIO overhead at that point
anyway.
pws
diff --git a/Src/input.c b/Src/input.c
index 92abaec..03d6476 100644
--- a/Src/input.c
+++ b/Src/input.c
@@ -147,6 +147,53 @@ shingetline(void)
for (;;) {
winch_unblock();
dont_queue_signals();
+#ifdef HAVE_FGETS
+ do {
+ errno = 0;
+ p = fgets(buf, BUFSIZ, bshin);
+ } while (!p && errno == EINTR);
+ winch_block();
+ if (!p) {
+ restore_queue_signals(q);
+ return NULL;
+ }
+ c = 0;
+ while (*p) {
+ if (imeta(STOUC(*p++)))
+ c++;
+ }
+ if (p > buf) {
+ /* p is pointing to '\0' */
+ ptrdiff_t nread = p - buf;
+ queue_signals();
+ line = zrealloc(line, ll + c + nread + 1);
+ if (c) {
+ char *dest = line + ll;
+ char *src = buf;
+ while (src < p) {
+ if (imeta(STOUC(*src))) {
+ *dest++ = Meta;
+ *dest++ = STOUC(*src++) ^ 32;
+ } else
+ *dest++ = *src++;
+ }
+ *dest++ = '\0';
+ } else {
+ /* copy null */
+ memcpy(line + ll, buf, nread + 1);
+ }
+ unqueue_signals();
+ /* fgets stops at first newline but stores '\0' after */
+ if (p[-1] == '\n') {
+ restore_queue_signals(q);
+ return line;
+ }
+ ll += nread;
+ } else {
+ restore_queue_signals(q);
+ return NULL;
+ }
+#else
do {
errno = 0;
c = fgetc(bshin);
@@ -178,6 +225,7 @@ shingetline(void)
p = buf;
unqueue_signals();
}
+#endif
}
}
diff --git a/configure.ac b/configure.ac
index 88da89e..2f19a73 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1325,7 +1325,8 @@ AC_CHECK_FUNCS(strftime strptime mktime timelocal \
cygwin_conv_path \
nanosleep \
srand_deterministic \
- setutxent getutxent endutxent getutent)
+ setutxent getutxent endutxent getutent \
+ fgets)
AC_FUNC_STRCOLL
AH_TEMPLATE([REALPATH_ACCEPTS_NULL],
Messages sorted by:
Reverse Date,
Date,
Thread,
Author