From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 8825 invoked by alias); 11 Oct 2015 06:20:56 -0000 Mailing-List: contact zsh-workers-help@zsh.org; run by ezmlm Precedence: bulk X-No-Archive: yes List-Id: Zsh Workers List List-Post: List-Help: X-Seq: 36827 Received: (qmail 29897 invoked from network); 11 Oct 2015 06:20:52 -0000 X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on f.primenet.com.au X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=ham autolearn_force=no version=3.4.0 X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:message-id:date:in-reply-to:comments :references:to:subject:mime-version:content-type; bh=LsGU241aYxEvjntzv+S/GnKWfXkAwRZMB5NM1x73Q4E=; b=ODz1Mp8i6pNieNTB9+leyO+RNxfhc+988/RYozs2Rf3OpdB4TK6E4GKYJL1wsZCUtC u9wP+rLuibngEmWgXr1IjuWiU8PItlA1eXUEbA3geGr5v2k7PFuSdpT9pIS/zL1uxJTE E0B8IdwzsKCYJmZysBNY1V+E1JfJCEP0eoElvSfUBJhexTQM7FUiUgvW235bUnSvukDM IDix8lH7qk9jEvbdXqoAfN6uRfpFep7P5SB9JZxjsuXdHGGcLI1xuqWUte+ITr0I2xjE Ov+XYHi8T8vUNtIZChxu3n1OrgA/ra3BIZhS2M02aleZKryIRTS6gTq4bF1SYlhblcpa i1Yg== X-Gm-Message-State: ALoCoQkeL2ZWMxY/qvBSPRX3HxqhzmnX3p8k1SibFXTQPRAtcZJP1cM0cVRtQrGvGxBx+0l19f3h X-Received: by 10.182.220.201 with SMTP id py9mr3783307obc.45.1444544448658; Sat, 10 Oct 2015 23:20:48 -0700 (PDT) From: Bart Schaefer Message-Id: <151010232045.ZM12931@torch.brasslantern.com> Date: Sat, 10 Oct 2015 23:20:45 -0700 In-Reply-To: <151010170623.ZM16166@torch.brasslantern.com> Comments: In reply to Bart Schaefer "Re: Slowdown around 5.0.5-dev-0" (Oct 10, 5:06pm) References: <151010105849.ZM10144@torch.brasslantern.com> <151010170623.ZM16166@torch.brasslantern.com> X-Mailer: OpenZMail Classic (0.9.2 24April2005) To: zsh-workers@zsh.org Subject: Re: Slowdown around 5.0.5-dev-0 MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii On Oct 10, 5:06pm, Bart Schaefer wrote: } } This suggests a couple of possible fixes, but I've run out of time to } experiment right now. OK, this is the least intrusive change I can think of that might make a difference. What this attempts to do is maintain a second pointer into the list of heaps that tells freeheap() where to start working. It's set on pushheap() and reset on popheap() so it freeheap() should avoid searching for free space in some arenas that were completely filled before pushheap() was called. However, it won't improve the performance if there are a whole lot of heap arenas each with a small amount of space available at the time of pushheap(). To improve THAT situation, I think we'd have to be willing to "leak" those small pieces of heap until a popheap() happens, and instead use at least one new arena following most calls to pushheap(). This might mean that zsh's memory footprint grows, but on modern hardware that may not be an issue. All tests pass with this change in place, let's see what it does with Sebastian's 89k array elements. diff --git a/Src/mem.c b/Src/mem.c index b9569ea..01072a3 100644 --- a/Src/mem.c +++ b/Src/mem.c @@ -127,6 +127,12 @@ static Heap heaps; static Heap fheap; +/* same as fheap, except in the preceding stack context (it will be the + * first heap from which space in the current context may be recovered + * when heap space is freed) */ + +static Heap fpop; + /**/ #ifdef ZSH_HEAP_DEBUG /* @@ -293,8 +299,11 @@ pushheap(void) h_push++; #endif + fpop = NULL; for (h = heaps; h; h = h->next) { DPUTS(!h->used, "BUG: empty heap"); + if (!fpop && h->used < ARENA_SIZEOF(h)) + fpop = h; hs = (Heapstack) zalloc(sizeof(*hs)); hs->next = h->sp; h->sp = hs; @@ -341,9 +350,10 @@ freeheap(void) * * However, if the arena to which fheap points is unused, we want to * free it, so we have no choice but to do the sweep for a new fheap. + * fpop is the first heap with free space following pushheap(). */ if (fheap && !fheap->sp) - fheap = NULL; /* We used to do this unconditionally */ + fheap = fpop; /* * In other cases, either fheap is already correct, or it has never * been set and this loop will do it, or it'll be reset from scratch @@ -417,7 +427,7 @@ popheap(void) h_pop++; #endif - fheap = NULL; + fheap = fpop = NULL; for (h = heaps; h; h = hn) { hn = h->next; if ((hs = h->sp)) { @@ -443,6 +453,8 @@ popheap(void) #endif if (!fheap && h->used < ARENA_SIZEOF(h)) fheap = h; + if (!fpop && h->sp && h->sp->used < ARENA_SIZEOF(h)) + fpop = h; zfree(hs, sizeof(*hs)); hl = h;