From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 10976 invoked from network); 15 Mar 2000 13:28:20 -0000 Received: from sunsite.auc.dk (130.225.51.30) by ns1.primenet.com.au with SMTP; 15 Mar 2000 13:28:20 -0000 Received: (qmail 26829 invoked by alias); 15 Mar 2000 13:28:09 -0000 Mailing-List: contact zsh-workers-help@sunsite.auc.dk; run by ezmlm Precedence: bulk X-No-Archive: yes X-Seq: 10148 Received: (qmail 26816 invoked from network); 15 Mar 2000 13:28:09 -0000 Date: Wed, 15 Mar 2000 14:28:07 +0100 (MET) Message-Id: <200003151328.OAA18970@beta.informatik.hu-berlin.de> From: Sven Wischnowsky To: zsh-workers@sunsite.auc.dk In-reply-to: Oliver Kiddle's message of Sun, 12 Mar 2000 15:44:25 +0000 Subject: Re: command completion taking ages Oliver Kiddle wrote: > If I press tab in a position where all commands are completed, I get a > very long delay. And of course we should have a look why this is so slow... It turned out that one of the main reasons was that permalloc() (called from the function that does $compstate[nmatches]) got called very often and re-calculated the list of matches again and again (of course). The patch below at least makes it re-use already calculated and perm-alloc'ed groups again if they didn't change. This already makes it more than twice as fast as it was before for me. It won't have much effect for people who don't use the group-name style, though. I played a bit with re-using already perm-alloc'ed matches, but that had surprisingly little effect, so I took it out again. Has anyone ever had a look at the output of `mem' (with zsh's allocation routines) after doing completion in command position with an empty prefix? Very interesting. I get some 300KB of free (i.e. unused) memory. Urgh. Maybe we should make it calculate the amount of memory needed for each group (there wouldn't be much overhead for this, I think), allocate only one big block and write everything in it. And then we could think about giving support for such relatively-short-lived-but-still-zalloc'ed blocks in mem.c, allocating them out of the way of normal zalloc'ed memory (e.g. using mmap() if available, like we do it for heaps). The hunks in mem.c just add some more information a bit of information to the output of `mem' that I've been missing once too often now. Bye Sven diff -ru ../z.old/Src/Zle/comp.h Src/Zle/comp.h --- ../z.old/Src/Zle/comp.h Wed Mar 15 12:53:10 2000 +++ Src/Zle/comp.h Wed Mar 15 13:49:04 2000 @@ -73,6 +73,8 @@ int *widths; /* column widths for listpacked */ int totl; /* total length */ int shortest; /* length of shortest match */ + Cmgroup perm; /* perm. alloced version of this group */ + int new; /* new matches since last permalloc() */ }; diff -ru ../z.old/Src/Zle/compcore.c Src/Zle/compcore.c --- ../z.old/Src/Zle/compcore.c Wed Mar 15 12:53:10 2000 +++ Src/Zle/compcore.c Wed Mar 15 13:53:45 2000 @@ -2174,6 +2174,7 @@ addlinknode((alt ? fmatches : matches), cm); newmatches = 1; + mgroup->new = 1; if (!complastprompt || !*complastprompt) dolastprompt = 0; @@ -2262,6 +2263,8 @@ mgroup->matches = NULL; mgroup->ylist = NULL; mgroup->expls = NULL; + mgroup->perm = NULL; + mgroup->new = 0; mgroup->lexpls = expls = newlinklist(); mgroup->lmatches = matches = newlinklist(); @@ -2519,12 +2522,12 @@ mod_export int permmatches(int last) { - Cmgroup g = amatches, n; + Cmgroup g = amatches, n, opm; Cmatch *p, *q; Cexpl *ep, *eq, e, o; LinkList mlist; static int fi = 0; - int nn, nl, ll, gn = 1, mn = 1, rn; + int nn, nl, ll, gn = 1, mn = 1, rn, ofi = fi; if (pmatches && !newmatches) { if (last && fi) @@ -2533,9 +2536,7 @@ } newmatches = fi = 0; - if (pmatches) - freematches(pmatches); - + opm = pmatches; pmatches = lmatches = NULL; nmatches = smatches = 0; @@ -2545,68 +2546,87 @@ fi = 1; } while (g) { - if (fi) - /* We have no matches, try ignoring fignore. */ - mlist = g->lfmatches; - else - mlist = g->lmatches; - - g->matches = makearray(mlist, 1, g->flags, &nn, &nl, &ll); - g->mcount = nn; - if ((g->lcount = nn - nl) < 0) - g->lcount = 0; - g->llcount = ll; - if (g->ylist) { - g->lcount = arrlen(g->ylist); - smatches = 2; - } - g->expls = (Cexpl *) makearray(g->lexpls, 0, 0, &(g->ecount), - NULL, NULL); + if (fi != ofi || !g->perm || g->new) { + if (fi) + /* We have no matches, try ignoring fignore. */ + mlist = g->lfmatches; + else + mlist = g->lmatches; + + g->matches = makearray(mlist, 1, g->flags, &nn, &nl, &ll); + g->mcount = nn; + if ((g->lcount = nn - nl) < 0) + g->lcount = 0; + g->llcount = ll; + if (g->ylist) { + g->lcount = arrlen(g->ylist); + smatches = 2; + } + g->expls = (Cexpl *) makearray(g->lexpls, 0, 0, &(g->ecount), + NULL, NULL); - g->ccount = 0; + g->ccount = 0; - nmatches += g->mcount; - smatches += g->lcount; + nmatches += g->mcount; + smatches += g->lcount; - n = (Cmgroup) zcalloc(sizeof(struct cmgroup)); - - if (!lmatches) - lmatches = n; - if (pmatches) - pmatches->prev = n; - n->next = pmatches; - pmatches = n; - n->prev = 0; - n->num = gn++; - - n->flags = g->flags; - n->mcount = g->mcount; - n->matches = p = (Cmatch *) zcalloc((n->mcount + 1) * sizeof(Cmatch)); - n->name = ztrdup(g->name); - for (q = g->matches; *q; q++, p++) - *p = dupmatch(*q, nbrbeg, nbrend); - *p = NULL; - - n->lcount = g->lcount; - n->llcount = g->llcount; - if (g->ylist) - n->ylist = zarrdup(g->ylist); - else - n->ylist = NULL; + n = (Cmgroup) zcalloc(sizeof(struct cmgroup)); - if ((n->ecount = g->ecount)) { - n->expls = ep = (Cexpl *) zcalloc((n->ecount + 1) * sizeof(Cexpl)); - for (eq = g->expls; (o = *eq); eq++, ep++) { - *ep = e = (Cexpl) zcalloc(sizeof(struct cexpl)); - e->count = (fi ? o->fcount : o->count); - e->str = ztrdup(o->str); + if (g->perm) { + g->perm->next = NULL; + freematches(g->perm); } - *ep = NULL; - } else - n->expls = NULL; + g->perm = n; - n->widths = NULL; + if (!lmatches) + lmatches = n; + if (pmatches) + pmatches->prev = n; + n->next = pmatches; + pmatches = n; + n->prev = NULL; + n->num = gn++; + n->flags = g->flags; + n->mcount = g->mcount; + n->matches = p = (Cmatch *) zcalloc((n->mcount + 1) * sizeof(Cmatch)); + n->name = ztrdup(g->name); + for (q = g->matches; *q; q++, p++) + *p = dupmatch(*q, nbrbeg, nbrend); + *p = NULL; + + n->lcount = g->lcount; + n->llcount = g->llcount; + if (g->ylist) + n->ylist = zarrdup(g->ylist); + else + n->ylist = NULL; + + if ((n->ecount = g->ecount)) { + n->expls = ep = (Cexpl *) zcalloc((n->ecount + 1) * sizeof(Cexpl)); + for (eq = g->expls; (o = *eq); eq++, ep++) { + *ep = e = (Cexpl) zcalloc(sizeof(struct cexpl)); + e->count = (fi ? o->fcount : o->count); + e->str = ztrdup(o->str); + } + *ep = NULL; + } else + n->expls = NULL; + n->widths = NULL; + } else { + if (!lmatches) + lmatches = g->perm; + if (pmatches) + pmatches->prev = g->perm; + g->perm->next = pmatches; + pmatches = g->perm; + g->perm->prev = NULL; + + nmatches += g->mcount; + smatches += g->lcount; + g->num = gn++; + } + g->new = 0; g = g->next; } for (g = pmatches; g; g = g->next) { @@ -2664,7 +2684,7 @@ while (g) { n = g->next; - + for (m = g->matches; *m; m++) freematch(*m, g->nbrbeg, g->nbrend); diff -ru ../z.old/Src/mem.c Src/mem.c --- ../z.old/Src/mem.c Wed Mar 15 12:53:07 2000 +++ Src/mem.c Wed Mar 15 14:26:18 2000 @@ -1219,7 +1219,7 @@ int i, ii, fi, ui, j; struct m_hdr *m, *mf, *ms; char *b, *c, buf[40]; - long u = 0, f = 0; + long u = 0, f = 0, to, cu; if (ops['v']) { printf("The lower and the upper addresses of the heap. Diff gives\n"); @@ -1242,13 +1242,15 @@ printf("values, i.e. the number of blocks of that size that is\n"); printf("currently allocated. Total is the product of size and diff,\n"); printf("i.e. the number of bytes that are allocated for blocks of\n"); - printf("this size.\n"); + printf("this size. The last field gives the accumulated number of\n"); + printf("bytes for all sizes.\n"); } - printf("\nsize\tmalloc\tfree\tdiff\ttotal\n"); - for (i = 0; i < 1024; i++) + printf("\nsize\tmalloc\tfree\tdiff\ttotal\tcum\n"); + for (i = 0, cu = 0; i < 1024; i++) if (m_m[i] || m_f[i]) - printf("%ld\t%d\t%d\t%d\t%ld\n", (long)i * M_ISIZE, m_m[i], m_f[i], - m_m[i] - m_f[i], (long)i * M_ISIZE * (m_m[i] - m_f[i])); + printf("%ld\t%d\t%d\t%d\t%ld\t%ld\n", + (long)i * M_ISIZE, m_m[i], m_f[i], m_m[i] - m_f[i], + (to = (long) i * M_ISIZE * (m_m[i] - m_f[i])), (cu += to)); if (m_m[i] || m_f[i]) printf("big\t%d\t%d\t%d\n", m_m[i], m_f[i], m_m[i] - m_f[i]); -- Sven Wischnowsky wischnow@informatik.hu-berlin.de