More performance optimizations (Charles Crain)
authorstevenknight <stevenknight@fdb21ef1-2011-0410-befe-b5e4ea1792b1>
Tue, 5 Feb 2002 20:28:24 +0000 (20:28 +0000)
committerstevenknight <stevenknight@fdb21ef1-2011-0410-befe-b5e4ea1792b1>
Tue, 5 Feb 2002 20:28:24 +0000 (20:28 +0000)
git-svn-id: http://scons.tigris.org/svn/scons/trunk@245 fdb21ef1-2011-0410-befe-b5e4ea1792b1

src/CHANGES.txt
src/engine/SCons/Node/__init__.py
src/engine/SCons/Scanner/C.py
src/engine/SCons/Sig/SigTests.py

index 5102b45dc3c761a55c53b530c1a15ad9b22a8687..037db1e1b50bd9ab11226e1f9de5d51f608f2b5e 100644 (file)
@@ -22,6 +22,9 @@ RELEASE 0.05 -
   - Compensate for a bug in os.path.normpath() that returns '' for './'
     on WIN32.
 
+  - More performance optimizations:  cache #include lines from files,
+    eliminate unnecessary calls.
+
   From Steven Knight:
 
   - Flush stdout after print so it intermixes correctly with stderr
index 03e347e38b2fa907bb6c247fb4bc1028af175d4a..1222b1e9b6c9d1f660ed041cc3f10aaf5f52ffd4 100644 (file)
@@ -71,6 +71,7 @@ class Node:
         self.csig = None
         self.use_signature = 1
         self.precious = None
+        self.found_includes = {}
 
     def build(self):
         """Actually build the node.   Return the status from the build."""
@@ -95,6 +96,8 @@ class Node:
         if stat:
             raise BuildError(node = self, errstr = "Error %d" % stat)
 
+        self.found_includes = {}
+
         # If we succesfully build a node, then we need to rescan for
         # implicit dependencies, since it might have changed on us.
 
index f3c99075efb3965477baef223359776b90e2b402..51235c3d3fca1ad19698761cf23a99ecc857330e 100644 (file)
@@ -38,6 +38,8 @@ import SCons.Util
 
 include_re = re.compile('^[ \t]*#[ \t]*include[ \t]+(<|")([\\w./\\\\]+)(>|")', re.M)
 
+include_cache = {}
+
 def CScan(fs = SCons.Node.FS.default_fs):
     "Return a prototype Scanner instance for scanning C/C++ source files"
     cs = CScanner(scan, "CScan", [fs, ()],
@@ -96,27 +98,31 @@ def scan(node, env, args = [SCons.Node.FS.default_fs, ()]):
     fs, cpppath = args
     nodes = []
 
-    if node.exists():
-
-        # cache the includes list in node so we only scan it once:
-        if hasattr(node, 'includes'):
-            includes = node.includes
-        else:
-            includes = include_re.findall(node.get_contents())
-            node.includes = includes
-
-        source_dir = node.get_dir()
+    try:
+        nodes = node.found_includes[cpppath]
+    except KeyError:
+        if node.exists():
 
-        for include in includes:
-            if include[0] == '"':
-                node = SCons.Util.find_file(include[1], (source_dir,) + cpppath,
-                                            fs.File)
+            # cache the includes list in node so we only scan it once:
+            if hasattr(node, 'includes'):
+                includes = node.includes
             else:
-                node = SCons.Util.find_file(include[1], cpppath + (source_dir,),
-                                            fs.File)
-
-            if not node is None:
-                nodes.append(node)
+                includes = include_re.findall(node.get_contents())
+                node.includes = includes
+
+            source_dir = node.get_dir()
+            
+            for include in includes:
+                if include[0] == '"':
+                    n = SCons.Util.find_file(include[1], (source_dir,) + cpppath,
+                                                fs.File)
+                else:
+                    n = SCons.Util.find_file(include[1], cpppath + (source_dir,),
+                                                fs.File)
+
+                if not n is None:
+                    nodes.append(n)
+        node.found_includes[cpppath] = nodes
 
     # Schwartzian transform from the Python FAQ Wizard
     def st(List, Metric):
@@ -129,7 +135,8 @@ def scan(node, env, args = [SCons.Node.FS.default_fs, ()]):
         return map(stripit, paired)
 
     def normalize(node):
-        return os.path.normpath(str(node))
+        return str(node)
 
     return st(nodes, normalize)
 
+
index bff6083ea759f8854fa8aad6dfac7d07b6be4d2f..e4c9421a2986bf30f1476f715db10af5d809bb75 100644 (file)
@@ -73,6 +73,13 @@ class DummyNode:
     def exists(self):
         return not self.file.contents is None
 
+    def cached_exists(self):
+        try:
+            return self.exists_cache
+        except AttributeError:
+            self.exists_cache = self.exists()
+            return self.exists_cache
+        
     def children(self):
         return self.sources + self.depends
 
@@ -287,6 +294,8 @@ class CalcTestCase(unittest.TestCase):
                 return self.kids
             def exists(self):
                 return 1
+            def cached_exists(self):
+                return 1
             def get_bsig(self):
                 return self.bsig
             def get_csig(self):
@@ -332,6 +341,8 @@ class CalcTestCase(unittest.TestCase):
         class NE(self.nodeclass):
             def exists(self):
                 return 0
+            def cached_exists(self):
+                return 0
             def has_signature(self):
                 return None
         class NN(self.nodeclass):