diff options
author | Adam Gross <grossag@vmware.com> | 2019-11-25 15:59:49 (GMT) |
---|---|---|
committer | Adam Gross <grossag@vmware.com> | 2019-11-25 15:59:49 (GMT) |
commit | 3b0b2b13b3b47886bd097685c863068a5ca8c5dd (patch) | |
tree | eb2201f478ae5d7d5a3d29c6700239429bc6726b | |
parent | 49b5f9ec268d6f913088cae0b2942f5c7a139693 (diff) | |
download | SCons-3b0b2b13b3b47886bd097685c863068a5ca8c5dd.zip SCons-3b0b2b13b3b47886bd097685c863068a5ca8c5dd.tar.gz SCons-3b0b2b13b3b47886bd097685c863068a5ca8c5dd.tar.bz2 |
Memoize environment.Value() to improve performance
The code I work on calls env.Value() often on the same values as part of
consolidating outside dependencies. This change improves performance of that
call by memoizing the results.
-rw-r--r-- | src/engine/SCons/Environment.py | 2 | ||||
-rw-r--r-- | src/engine/SCons/Node/Python.py | 30 |
2 files changed, 25 insertions, 7 deletions
diff --git a/src/engine/SCons/Environment.py b/src/engine/SCons/Environment.py index 1296f54..968cc9f 100644 --- a/src/engine/SCons/Environment.py +++ b/src/engine/SCons/Environment.py @@ -2220,7 +2220,7 @@ class Base(SubstitutionEnvironment): def Value(self, value, built_value=None): """ """ - return SCons.Node.Python.Value(value, built_value) + return SCons.Node.Python.ValueWithMemo(value, built_value) def VariantDir(self, variant_dir, src_dir, duplicate=1): variant_dir = self.arg2nodes(variant_dir, self.fs.Dir)[0] diff --git a/src/engine/SCons/Node/Python.py b/src/engine/SCons/Node/Python.py index 4a62f04..f817402 100644 --- a/src/engine/SCons/Node/Python.py +++ b/src/engine/SCons/Node/Python.py @@ -31,6 +31,9 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" import SCons.Node +_memoLookupMap = {} + + class ValueNodeInfo(SCons.Node.NodeInfoBase): __slots__ = ('csig',) current_version_id = 2 @@ -38,18 +41,18 @@ class ValueNodeInfo(SCons.Node.NodeInfoBase): field_list = ['csig'] def str_to_node(self, s): - return Value(s) + return ValueWithMemo(s) def __getstate__(self): """ Return all fields that shall be pickled. Walk the slots in the class - hierarchy and add those to the state dictionary. If a '__dict__' slot is - available, copy all entries to the dictionary. Also include the version - id, which is fixed for all instances of a class. + hierarchy and add those to the state dictionary. If a '__dict__' slot + is available, copy all entries to the dictionary. Also include the + version id, which is fixed for all instances of a class. """ state = getattr(self, '__dict__', {}).copy() for obj in type(self).mro(): - for name in getattr(obj,'__slots__',()): + for name in getattr(obj, '__slots__', ()): if hasattr(self, name): state[name] = getattr(self, name) @@ -76,6 +79,7 @@ class ValueBuildInfo(SCons.Node.BuildInfoBase): __slots__ = () current_version_id = 2 + class Value(SCons.Node.Node): """A class for Python variables, typically passed on the command line or generated by a script, but not from a file or some other source. @@ -148,7 +152,6 @@ class Value(SCons.Node.Node): # Already encoded as python2 str are bytes return text_contents - def changed_since_last_build(self, target, prev_ni): cur_csig = self.get_csig() try: @@ -173,6 +176,21 @@ class Value(SCons.Node.Node): self.get_ninfo().csig = contents return contents + +def ValueWithMemo(value, built_value=None): + # No current support for memoizing a value that needs to be built. + if built_value: + return Value(value, built_value) + + value_str = str(value) + if value_str in _memoLookupMap: + return _memoLookupMap[value_str] + + v = Value(value) + _memoLookupMap[value_str] = v + return v + + # Local Variables: # tab-width:4 # indent-tabs-mode:nil |