diff options
author | Steven Knight <knight@baldmt.com> | 2003-02-11 11:27:07 (GMT) |
---|---|---|
committer | Steven Knight <knight@baldmt.com> | 2003-02-11 11:27:07 (GMT) |
commit | 08d5aaf06f5030d59404a586164eb6121c538973 (patch) | |
tree | 603b1aa19ce8717891505490845e61bcc77eb0ac /src | |
parent | 0f5282ba0d7a5b96c2e5bec6eedb3027aa3fd52a (diff) | |
download | SCons-08d5aaf06f5030d59404a586164eb6121c538973.zip SCons-08d5aaf06f5030d59404a586164eb6121c538973.tar.gz SCons-08d5aaf06f5030d59404a586164eb6121c538973.tar.bz2 |
Fix some performance problems with the --implicit-cache option. (Anthony Roach)
Diffstat (limited to 'src')
-rw-r--r-- | src/CHANGES.txt | 2 | ||||
-rw-r--r-- | src/engine/SCons/Node/FS.py | 20 | ||||
-rw-r--r-- | src/engine/SCons/Node/__init__.py | 36 | ||||
-rw-r--r-- | src/engine/SCons/Sig/__init__.py | 36 |
4 files changed, 60 insertions, 34 deletions
diff --git a/src/CHANGES.txt b/src/CHANGES.txt index 068dc3d..a8c621d 100644 --- a/src/CHANGES.txt +++ b/src/CHANGES.txt @@ -96,6 +96,8 @@ RELEASE 0.11 - XXX - Allow the same object files on Win32 to be linked into either shared or static libraries. + - Cache implicit cache values when using --implicit-cache. + RELEASE 0.10 - Thu, 16 Jan 2003 04:11:46 -0600 diff --git a/src/engine/SCons/Node/FS.py b/src/engine/SCons/Node/FS.py index 2057797..651d280 100644 --- a/src/engine/SCons/Node/FS.py +++ b/src/engine/SCons/Node/FS.py @@ -850,34 +850,26 @@ class File(Entry): else: return 0 - def calc_signature(self, calc): + def calc_signature(self, calc, cache=None): """ Select and calculate the appropriate build signature for a File. self - the File node calc - the signature calculation module + cache - alternate node to use for the signature cache returns - the signature - - This method does not store the signature in the node or - in the .sconsign file. """ if self.has_builder(): if SCons.Sig.build_signature: - if not hasattr(self, 'bsig'): - self.set_bsig(calc.bsig(self.rfile())) - return self.get_bsig() + return calc.bsig(self.rfile(), self) else: - if not hasattr(self, 'csig'): - self.set_csig(calc.csig(self.rfile())) - return self.get_csig() + return calc.csig(self.rfile(), self) elif not self.rexists(): return None else: - if not hasattr(self, 'csig'): - self.set_csig(calc.csig(self.rfile())) - return self.get_csig() - + return calc.csig(self.rfile(), self) + def store_csig(self): self.dir.sconsign().set_csig(self.name, self.get_csig()) diff --git a/src/engine/SCons/Node/__init__.py b/src/engine/SCons/Node/__init__.py index e1bc8f1..600c478 100644 --- a/src/engine/SCons/Node/__init__.py +++ b/src/engine/SCons/Node/__init__.py @@ -255,6 +255,22 @@ class Node: return deps + # cache used to make implicit_factory fast. + implicit_factory_cache = {} + + def implicit_factory(self, path): + """ + Turn a cache implicit dependency path into a node. + This is called so many times that doing caching + here is a significant perforamnce boost. + """ + try: + return self.implicit_factory_cache[path] + except KeyError: + n = self.builder.source_factory(path) + self.implicit_factory_cache[path] = n + return n + def scan(self): """Scan this node's dependents for implicit dependencies.""" # Don't bother scanning non-derived files, because we don't @@ -269,7 +285,7 @@ class Node: if implicit_cache and not implicit_deps_changed: implicit = self.get_stored_implicit() if implicit is not None: - implicit = map(self.builder.source_factory, implicit) + implicit = map(self.implicit_factory, implicit) self._add_child(self.implicit, implicit) calc = SCons.Sig.default_calc if implicit_deps_unchanged or calc.current(self, calc.bsig(self)): @@ -306,33 +322,25 @@ class Node: return self.env = env - def calc_signature(self, calc): + def calc_signature(self, calc, cache=None): """ Select and calculate the appropriate build signature for a node. self - the node calc - the signature calculation module + cache - alternate node to use for the signature cache returns - the signature - - This method does not store the signature in the node or - in the .sconsign file. """ if self.has_builder(): if SCons.Sig.build_signature: - if not hasattr(self, 'bsig'): - self.set_bsig(calc.bsig(self)) - return self.get_bsig() + return calc.bsig(self, cache) else: - if not hasattr(self, 'csig'): - self.set_csig(calc.csig(self)) - return self.get_csig() + return calc.csig(self, cache) elif not self.exists(): return None else: - if not hasattr(self, 'csig'): - self.set_csig(calc.csig(self)) - return self.get_csig() + return calc.csig(self, cache) def get_bsig(self): """Get the node's build signature (based on the signatures diff --git a/src/engine/SCons/Sig/__init__.py b/src/engine/SCons/Sig/__init__.py index 939f36f..196d065 100644 --- a/src/engine/SCons/Sig/__init__.py +++ b/src/engine/SCons/Sig/__init__.py @@ -249,12 +249,13 @@ class Calculator: self.module = module self.max_drift = max_drift - def bsig(self, node): + def bsig(self, node, cache=None): """ Generate a node's build signature, the digested signatures of its dependency files and build information. node - the node whose sources will be collected + cache - alternate node to use for the signature cache returns - the build signature This no longer handles the recursive descent of the @@ -262,27 +263,50 @@ class Calculator: already built and updated by someone else, if that's what's wanted. """ - sigs = map(lambda n, c=self: n.calc_signature(c), node.children()) + + if cache is None: cache = node + + bsig = cache.get_bsig() + if bsig is not None: + return bsig + + children = node.children() + + # double check bsig, because the call to childre() above may + # have set it: + bsig = cache.get_bsig() + if bsig is not None: + return bsig + + sigs = map(lambda n, c=self: n.calc_signature(c), children) if node.has_builder(): sigs.append(self.module.signature(node.builder_sig_adapter())) bsig = self.module.collect(filter(lambda x: not x is None, sigs)) - node.set_bsig(bsig) + cache.set_bsig(bsig) # don't store the bsig here, because it isn't accurate until # the node is actually built. return bsig - def csig(self, node): + def csig(self, node, cache=None): """ Generate a node's content signature, the digested signature of its content. node - the node + cache - alternate node to use for the signature cache returns - the content signature """ + + if cache is None: cache = node + + csig = cache.get_csig() + if csig is not None: + return csig + if self.max_drift >= 0: info = node.get_prevsiginfo() else: @@ -295,12 +319,12 @@ class Calculator: csig = info[2] # Set the csig here so it doesn't get recalculated unnecessarily # and so it's set when the .sconsign file gets written - node.set_csig(csig) + cache.set_csig(csig) else: csig = self.module.signature(node) # Set the csig here so it doesn't get recalculated unnecessarily # and so it's set when the .sconsign file gets written - node.set_csig(csig) + cache.set_csig(csig) if self.max_drift >= 0 and (time.time() - mtime) > self.max_drift: node.store_csig() |