On Wed, 2011-04-06 at 12:35 +0100, Michael Meeks wrote:
> Anyhow - one problem we are seeing is that as we load and parse the
> ~50Mb of dependencies that we need (for part of writer) we are statting
> the same files involved in dependencies sometimes a thousand times or
> so. We do around 700k stats with lots of duplication.
> 
> These ~all come from calling 'glob'; I append a patch that tries to
> call glob only if needed - it could be done more prettily:

Try this one and see if it works as well.

-- 
-------------------------------------------------------------------------------
 Paul D. Smith <psm...@gnu.org>          Find some GNU make tips at:
 http://www.gnu.org                      http://make.mad-scientist.net
 "Please remain calm...I may be mad, but I am a professional." --Mad Scientist
? gnumake.supp
? log.1
? vg.out
? x.out
? doc/gendocs_template
? doc/manual
Index: read.c
===================================================================
RCS file: /sources/make/make/read.c,v
retrieving revision 1.197
diff -u -r1.197 read.c
--- read.c	18 Apr 2011 01:25:20 -0000	1.197
+++ read.c	18 Apr 2011 01:59:14 -0000
@@ -2898,6 +2898,7 @@
       const char *name;
       const char **nlist = 0;
       char *tildep = 0;
+      int globme = 1;
 #ifndef NO_ARCHIVES
       char *arname = 0;
       char *memname = 0;
@@ -3106,32 +3107,40 @@
 	}
 #endif /* !NO_ARCHIVES */
 
-      switch (glob (name, GLOB_NOSORT|GLOB_ALTDIRFUNC, NULL, &gl))
-	{
-	case GLOB_NOSPACE:
-	  fatal (NILF, _("virtual memory exhausted"));
-
-	case 0:
-          /* Success.  */
-          i = gl.gl_pathc;
-          nlist = (const char **)gl.gl_pathv;
-          break;
-
-        case GLOB_NOMATCH:
-          /* If we want only existing items, skip this one.  */
-          if (flags & PARSEFS_EXISTS)
-            {
-              i = 0;
-              break;
-            }
-          /* FALLTHROUGH */
-
-	default:
-          /* By default keep this name.  */
+      /* glob() is expensive: don't call it unless we need to.  */
+      if (!(flags & PARSEFS_EXISTS) || strpbrk (name, "?*[") == NULL)
+        {
+          globme = 0;
           i = 1;
           nlist = &name;
-          break;
-	}
+        }
+      else
+        switch (glob (name, GLOB_NOSORT|GLOB_ALTDIRFUNC, NULL, &gl))
+          {
+          case GLOB_NOSPACE:
+            fatal (NILF, _("virtual memory exhausted"));
+
+          case 0:
+            /* Success.  */
+            i = gl.gl_pathc;
+            nlist = (const char **)gl.gl_pathv;
+            break;
+
+          case GLOB_NOMATCH:
+            /* If we want only existing items, skip this one.  */
+            if (flags & PARSEFS_EXISTS)
+              {
+                i = 0;
+                break;
+              }
+            /* FALLTHROUGH */
+
+          default:
+            /* By default keep this name.  */
+            i = 1;
+            nlist = &name;
+            break;
+          }
 
       /* For each matched element, add it to the list.  */
       while (i-- > 0)
@@ -3171,7 +3180,8 @@
 #endif /* !NO_ARCHIVES */
           NEWELT (concat (2, prefix, nlist[i]));
 
-      globfree (&gl);
+      if (globme)
+        globfree (&gl);
 
 #ifndef NO_ARCHIVES
       if (arname)
_______________________________________________
Bug-make mailing list
Bug-make@gnu.org
http://lists.gnu.org/mailman/listinfo/bug-make

Reply via email to