summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorSteven Knight <knight@baldmt.com>2002-02-05 20:28:24 (GMT)
committerSteven Knight <knight@baldmt.com>2002-02-05 20:28:24 (GMT)
commit5cadc347bec33395f08d9d7a999628a53e9ff69f (patch)
treec97b0dc76fa573f7939aa4b2e729e0f2c00b6a32 /src
parentf6c20c8f66928d7d9845717cca12770dbfc86a59 (diff)
downloadSCons-5cadc347bec33395f08d9d7a999628a53e9ff69f.zip
SCons-5cadc347bec33395f08d9d7a999628a53e9ff69f.tar.gz
SCons-5cadc347bec33395f08d9d7a999628a53e9ff69f.tar.bz2
More performance optimizations (Charles Crain)
Diffstat (limited to 'src')
-rw-r--r--src/CHANGES.txt3
-rw-r--r--src/engine/SCons/Node/__init__.py3
-rw-r--r--src/engine/SCons/Scanner/C.py47
-rw-r--r--src/engine/SCons/Sig/SigTests.py11
4 files changed, 44 insertions, 20 deletions
diff --git a/src/CHANGES.txt b/src/CHANGES.txt
index 5102b45..037db1e 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 03e347e..1222b1e 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 f3c9907..51235c3 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 bff6083..e4c9421 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):