From 4dcf7340e288478bafbfc5639a2911307ad2adbd Mon Sep 17 00:00:00 2001 From: stevenknight Date: Tue, 5 Feb 2002 20:28:24 +0000 Subject: [PATCH] More performance optimizations (Charles Crain) git-svn-id: http://scons.tigris.org/svn/scons/trunk@245 fdb21ef1-2011-0410-befe-b5e4ea1792b1 --- src/CHANGES.txt | 3 ++ src/engine/SCons/Node/__init__.py | 3 ++ src/engine/SCons/Scanner/C.py | 47 ++++++++++++++++++------------- src/engine/SCons/Sig/SigTests.py | 11 ++++++++ 4 files changed, 44 insertions(+), 20 deletions(-) diff --git a/src/CHANGES.txt b/src/CHANGES.txt index 5102b45d..037db1e1 100644 --- a/src/CHANGES.txt +++ b/src/CHANGES.txt @@ -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 diff --git a/src/engine/SCons/Node/__init__.py b/src/engine/SCons/Node/__init__.py index 03e347e3..1222b1e9 100644 --- a/src/engine/SCons/Node/__init__.py +++ b/src/engine/SCons/Node/__init__.py @@ -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. diff --git a/src/engine/SCons/Scanner/C.py b/src/engine/SCons/Scanner/C.py index f3c99075..51235c3d 100644 --- a/src/engine/SCons/Scanner/C.py +++ b/src/engine/SCons/Scanner/C.py @@ -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) + diff --git a/src/engine/SCons/Sig/SigTests.py b/src/engine/SCons/Sig/SigTests.py index bff6083e..e4c9421a 100644 --- a/src/engine/SCons/Sig/SigTests.py +++ b/src/engine/SCons/Sig/SigTests.py @@ -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): -- 2.26.2