Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: A patch with hashtable optimization, which doesn't work



There are no performance gains from keeping the collision list sorted. Tried many tests and nothing.

Tried to optimize mkautofn, to speed up sourcing zcompdump. The idea is simple – make single allocation, not two. However also no performance gains visible:

@@ -3483,15 +3483,15 @@ mkautofn(Shfunc shf)
 {
     Eprog p;

-    p = (Eprog) zalloc(sizeof(*p));
+    p = (Eprog) zalloc(sizeof(*p) + 5 * sizeof(wordcode));
     p->len = 5 * sizeof(wordcode);
-    p->prog = (Wordcode) zalloc(p->len);
+    p->prog = (Wordcode) (((char*)p)+sizeof(*p));
     p->strs = NULL;
     p->shf = shf;
     p->npats = 0;
     p->nref = 1; /* allocated from permanent storage */
     p->pats = (Patprog *) p->prog;
-    p->flags = EF_REAL;
+    p->flags = EF_REAL_SINGLE; /* no allocation for p->prog */

Attached is a full patch. Maybe it will inspire someone. I think that if sourcing time of zcompdump could drop from 55 ms to 35 ms it would be a great success. Tried callgrind on zsh -f sourcing the file, and it said:

22,888,884  _platform_strcmp [/usr/lib/system/libsystem_platform.dylib]
18,067,499  ImageLoaderMachOCompressed::trieWalk(unsigned char const*, unsigned char const*, char const*) [/usr/lib/dyld]
12,041,235  ecstrcode [/usr/local/bin/zsh]
 4,877,588  _pthread_mutex_unlock_slow [/usr/lib/system/libsystem_pthread.dylib]
 3,330,755  _pthread_mutex_lock_slow [/usr/lib/system/libsystem_pthread.dylib]
 2,937,243  ingetc [/usr/local/bin/zsh]
 1,854,600  stringsubst [/usr/local/bin/zsh]

So there's no allocation there. Tried to find something in ecstrcode but no luck.

Best regards,
Sebastian Gniazdowski

On 18 maja 2017 at 14:17:27, Sebastian Gniazdowski (psprint@xxxxxxxxxxx) wrote:
> On 18 maja 2017 at 12:15:29, Sebastian Gniazdowski (psprint@xxxxxxxxxxx) wrote:
> > Hello,
> > it is really simple to keep collision lists sorted. However, I get error about typeset  
> > not being found. Debugged that typeset is inserted into builtintab. I am pretty exhausted,  
> > maybe someone will have a revelation on this. Debugged that typeset is being searched  
> > in:
>  
> Found it, missing return NULL here below, writing so that no one wastes time, will now  
> test performance.

--
Sebastian Gniazdowski
psprint /at/ zdharma.org
diff --git a/Src/builtin.c b/Src/builtin.c
index 063644e..680b19a 100644
--- a/Src/builtin.c
+++ b/Src/builtin.c
@@ -3483,15 +3483,15 @@ mkautofn(Shfunc shf)
 {
     Eprog p;
 
-    p = (Eprog) zalloc(sizeof(*p));
+    p = (Eprog) zalloc(sizeof(*p) + 5 * sizeof(wordcode));
     p->len = 5 * sizeof(wordcode);
-    p->prog = (Wordcode) zalloc(p->len);
+    p->prog = (Wordcode) (((char*)p)+sizeof(*p));
     p->strs = NULL;
     p->shf = shf;
     p->npats = 0;
     p->nref = 1; /* allocated from permanent storage */
     p->pats = (Patprog *) p->prog;
-    p->flags = EF_REAL;
+    p->flags = EF_REAL_SINGLE; /* no allocation for p->prog */
     p->dump = NULL;
 
     p->prog[0] = WCB_LIST((Z_SYNC | Z_END), 0);
diff --git a/Src/exec.c b/Src/exec.c
index debb0ae..088080b 100644
--- a/Src/exec.c
+++ b/Src/exec.c
@@ -4973,7 +4973,13 @@ execfuncdef(Estate state, Eprog redir_prog)
 	    prog = (Eprog) zhalloc(sizeof(*prog));
 	    prog->nref = -1; /* on the heap */
 	} else {
-	    prog = (Eprog) zalloc(sizeof(*prog));
+            if (state->prog->dump || !names) {
+                prog = (Eprog) zalloc(sizeof(*prog));
+            } else {
+                /* The EF_REAL path below */
+                prog = (Eprog) zalloc(sizeof(*prog) + len);
+                prog->pats = pp = (Patprog *) (((char*)prog)+sizeof(*prog));
+            }
 	    prog->nref = 1; /* allocated from permanent storage */
 	}
 	prog->npats = npats;
@@ -4992,8 +4998,11 @@ execfuncdef(Estate state, Eprog redir_prog)
 	    prog->prog = state->pc;
 	    prog->strs = state->strs + sbeg;
 	} else {
-	    prog->flags = EF_REAL;
-	    prog->pats = pp = (Patprog *) zalloc(len);
+            /* The EF_REAL path */
+	    prog->flags = EF_REAL_SINGLE;
+	    // prog->pats = pp = (Patprog *) zalloc(len);
+            // -->
+            // prog->pats = pp = (((char*)prog)+sizeof(*prog));
 	    prog->prog = (Wordcode) (prog->pats + npats);
 	    prog->strs = (char *) (prog->prog + nprg);
 	    prog->dump = NULL;
diff --git a/Src/parse.c b/Src/parse.c
index 8769baa..1e1c528 100644
--- a/Src/parse.c
+++ b/Src/parse.c
@@ -504,18 +504,28 @@ bld_eprog(int heap)
 
     ecadd(WCB_END());
 
-    ret = heap ? (Eprog) zhalloc(sizeof(*ret)) : (Eprog) zalloc(sizeof(*ret));
-    ret->len = ((ecnpats * sizeof(Patprog)) +
-		(ecused * sizeof(wordcode)) +
-		ecsoffs);
-    ret->npats = ecnpats;
-    ret->nref = heap ? -1 : 1;
-    ret->pats = heap ? (Patprog *) zhalloc(ret->len) :
-	(Patprog *) zshcalloc(ret->len);
+    if ( heap ) {
+        ret = (Eprog) zhalloc(sizeof(*ret));
+        ret->len = ((ecnpats * sizeof(Patprog)) +
+                (ecused * sizeof(wordcode)) +
+                ecsoffs);
+        ret->npats = ecnpats;
+        ret->nref = -1;
+        ret->pats = (Patprog *) zhalloc(ret->len);
+    } else {
+        int len = ((ecnpats * sizeof(Patprog)) +
+                (ecused * sizeof(wordcode)) +
+                ecsoffs);
+        ret = (Eprog) zalloc(sizeof(*ret) + len);
+        ret->len = len;
+        ret->npats = ecnpats;
+        ret->nref = 1;
+        ret->pats = (Patprog *) (((char*)ret)+sizeof(*ret));
+    }
     ret->prog = (Wordcode) (ret->pats + ecnpats);
     ret->strs = (char *) (ret->prog + ecused);
     ret->shf = NULL;
-    ret->flags = heap ? EF_HEAP : EF_REAL;
+    ret->flags = heap ? EF_HEAP : EF_REAL_SINGLE;
     ret->dump = NULL;
     for (l = 0; l < ecnpats; l++)
 	ret->pats[l] = dummy_patprog1;
@@ -2709,9 +2719,14 @@ freeeprog(Eprog p)
 	    if (p->dump) {
 		decrdumpcount(p->dump);
 		zfree(p->pats, p->npats * sizeof(Patprog));
-	    } else
-		zfree(p->pats, p->len);
-	    zfree(p, sizeof(*p));
+	    } else {
+                if ( (p->flags & EF_REAL_SINGLE) == 0 )
+                    zfree(p->pats, p->len);
+            }
+            if ( (p->flags & EF_REAL_SINGLE) )
+                zfree(p, sizeof(*p) + p->len);
+            else
+                zfree(p, sizeof(*p));
 	}
     }
 }
diff --git a/Src/zsh.h b/Src/zsh.h
index 22f73f8..ab70cb7 100644
--- a/Src/zsh.h
+++ b/Src/zsh.h
@@ -797,6 +797,7 @@ struct eprog {
 #define EF_HEAP 2
 #define EF_MAP  4
 #define EF_RUN  8
+#define EF_REAL_SINGLE 16
 
 typedef struct estate *Estate;
 


Messages sorted by: Reverse Date, Date, Thread, Author