From eb28a959d95053d64d74df86d61dee3f8921dbd3 Mon Sep 17 00:00:00 2001 From: stevenknight Date: Tue, 1 Feb 2005 12:02:12 +0000 Subject: [PATCH] Reduce the number of actions created by caching generated LazyActions. git-svn-id: http://scons.tigris.org/svn/scons/trunk@1222 fdb21ef1-2011-0410-befe-b5e4ea1792b1 --- src/CHANGES.txt | 3 +++ src/engine/SCons/Action.py | 30 +++++++++++++++++++++++------- src/engine/SCons/ActionTests.py | 6 ++++-- 3 files changed, 30 insertions(+), 9 deletions(-) diff --git a/src/CHANGES.txt b/src/CHANGES.txt index eafac2d1..db0145b2 100644 --- a/src/CHANGES.txt +++ b/src/CHANGES.txt @@ -187,6 +187,9 @@ RELEASE 0.97 - XXX - Speed things up when there are lists of targets and/or sources by getting rid of some N^2 walks of the lists involved. + - Cache evaluation of LazyActions so we don't create a new object + for each invocation. + From Wayne Lee: - Avoid "maximum recursion limit" errors when removing $(-$) pairs diff --git a/src/engine/SCons/Action.py b/src/engine/SCons/Action.py index a3b62eb9..fa8f1d25 100644 --- a/src/engine/SCons/Action.py +++ b/src/engine/SCons/Action.py @@ -232,7 +232,7 @@ class ActionBase: def presub_lines(self, env): # CommandGeneratorAction needs a real environment # in order to return the proper string here, since - # it may call LazyCmdGenerator, which looks up a key + # it may call LazyAction, which looks up a key # in that env. So we temporarily remember the env here, # and CommandGeneratorAction will use this env # when it calls its _generate method. @@ -482,9 +482,9 @@ class CommandGeneratorAction(ActionBase): """ return self._generate(target, source, env, 1).get_contents(target, source, env) -# Ooh, polymorphism -- pretty scary, eh, kids? -# -# A LazyCmdAction is a kind of hybrid generator and command action for + + +# A LazyAction is a kind of hybrid generator and command action for # strings of the form "$VAR". These strings normally expand to other # strings (think "$CCCOM" to "$CC -c -o $TARGET $SOURCE"), but we also # want to be able to replace them with functions in the construction @@ -498,10 +498,13 @@ class CommandGeneratorAction(ActionBase): # the corresponding CommandAction method to do the heavy lifting. # If not, then we call the same-named CommandGeneratorAction method. # The CommandGeneratorAction methods work by using the overridden -# _generate() method, uses our own way of handling "generation" of an -# action based on what's in the construction variable. +# _generate() method, that is, our own way of handling "generation" of +# an action based on what's in the construction variable. class LazyAction(CommandGeneratorAction, CommandAction): + + __metaclass__ = SCons.Memoize.Memoized_Metaclass + def __init__(self, var, *args, **kw): if __debug__: logInstanceCreation(self) apply(CommandAction.__init__, (self, '$'+var)+args, kw) @@ -514,13 +517,17 @@ class LazyAction(CommandGeneratorAction, CommandAction): return CommandAction return CommandGeneratorAction - def _generate(self, target, source, env, for_signature): + def _generate_cache(self, env): + """__cacheable__""" c = env.get(self.var, '') gen_cmd = apply(Action, (c,), self.gen_kw) if not gen_cmd: raise SCons.Errors.UserError("$%s value %s cannot be used to create an Action." % (self.var, repr(c))) return gen_cmd + def _generate(self, target, source, env, for_signature): + return self._generate_cache(env) + def __call__(self, target, source, env, *args, **kw): args = (self, target, source, env) + args c = self.get_parent_class(env) @@ -530,6 +537,15 @@ class LazyAction(CommandGeneratorAction, CommandAction): c = self.get_parent_class(env) return c.get_contents(self, target, source, env) +if not SCons.Memoize.has_metaclass: + _Base = LazyAction + class LazyAction(SCons.Memoize.Memoizer, _Base): + def __init__(self, *args, **kw): + SCons.Memoize.Memoizer.__init__(self) + apply(_Base.__init__, (self,)+args, kw) + + + class FunctionAction(_ActionAction): """Class for Python function actions.""" diff --git a/src/engine/SCons/ActionTests.py b/src/engine/SCons/ActionTests.py index 4bcb0843..36117a4c 100644 --- a/src/engine/SCons/ActionTests.py +++ b/src/engine/SCons/ActionTests.py @@ -1491,9 +1491,11 @@ class LazyActionTestCase(unittest.TestCase): def f(target, source, env): pass a = SCons.Action.Action('$BAR') - s = a.genstring([], [], env=Environment(BAR=f, s=self)) + env1 = Environment(BAR=f, s=self) + env2 = Environment(BAR='xxx', s=self) + s = a.genstring([], [], env=env1) assert s == "f(target, source, env)", s - s = a.genstring([], [], env=Environment(BAR='xxx', s=self)) + s = a.genstring([], [], env=env2) assert s == 'xxx', s def test_execute(self): -- 2.26.2