diff options
author | Steven Knight <knight@baldmt.com> | 2005-03-04 21:27:30 (GMT) |
---|---|---|
committer | Steven Knight <knight@baldmt.com> | 2005-03-04 21:27:30 (GMT) |
commit | 213996506374ad40fc7ee4949e2be3790ead99d9 (patch) | |
tree | e994d5104a10b6dd448afee90cd411931cf6670a /src | |
parent | 3bf4475522d2a24910b147a607dcd9f0d980097f (diff) | |
download | SCons-213996506374ad40fc7ee4949e2be3790ead99d9.zip SCons-213996506374ad40fc7ee4949e2be3790ead99d9.tar.gz SCons-213996506374ad40fc7ee4949e2be3790ead99d9.tar.bz2 |
Optimize out N*M suffix matching in Builder.py.
Diffstat (limited to 'src')
-rw-r--r-- | src/engine/SCons/Builder.py | 39 | ||||
-rw-r--r-- | src/engine/SCons/Debug.py | 48 | ||||
-rw-r--r-- | src/engine/SCons/Script/Main.py | 5 |
3 files changed, 77 insertions, 15 deletions
diff --git a/src/engine/SCons/Builder.py b/src/engine/SCons/Builder.py index 39466a5..8d99a32 100644 --- a/src/engine/SCons/Builder.py +++ b/src/engine/SCons/Builder.py @@ -721,23 +721,32 @@ class MultiStepBuilder(BuilderBase): src_suffixes = self.src_suffixes(env) + def match_src_suffix(node, src_suffixes=src_suffixes): + # This reaches directly into the Node.name attribute (instead + # of using an accessor function) for performance reasons. + return filter(lambda s, n=node.name: + n[-len(s):] == s, + src_suffixes) + for snode in slist: - for srcsuf in src_suffixes: - if str(snode)[-len(srcsuf):] == srcsuf and sdict.has_key(srcsuf): - tgt = sdict[srcsuf]._execute(env, None, [snode], overwarn) - # If the subsidiary Builder returned more than one target, - # then filter out any sources that this Builder isn't - # capable of building. - if len(tgt) > 1: - tgt = filter(lambda x, self=self, suf=src_suffixes, e=env: - self.splitext(SCons.Util.to_String(x),e)[1] in suf, - tgt) - final_sources.extend(tgt) - snode = None - break - if snode: + name = snode.name + match = match_src_suffix(snode) + if match: + try: + bld = sdict[match[0]] + except KeyError: + final_sources.append(snode) + else: + tlist = bld._execute(env, None, [snode], overwarn) + # If the subsidiary Builder returned more than one + # target, then filter out any sources that this + # Builder isn't capable of building. + if len(tlist) > 1: + tlist = filter(match_src_suffix, tlist) + final_sources.extend(tlist) + else: final_sources.append(snode) - + return BuilderBase._execute(self, env, target, final_sources, overwarn) def get_src_builders(self, env): diff --git a/src/engine/SCons/Debug.py b/src/engine/SCons/Debug.py index 0d2d85d..bf7ed43 100644 --- a/src/engine/SCons/Debug.py +++ b/src/engine/SCons/Debug.py @@ -104,3 +104,51 @@ else: def memory(): res = resource.getrusage(resource.RUSAGE_SELF) return res[4] + + + +caller_dicts = {} + +def caller(back=0): + import traceback + tb = traceback.extract_stack(limit=3+back) + key = tb[1][:3] + try: + entry = caller_dicts[key] + except KeyError: + entry = caller_dicts[key] = {} + key = tb[0][:3] + try: + entry[key] = entry[key] + 1 + except KeyError: + entry[key] = 1 + +def dump_caller_counts(file=sys.stdout): + keys = caller_dicts.keys() + keys.sort() + for k in keys: + file.write("Callers of %s:%d(%s):\n" % func_shorten(k)) + counts = caller_dicts[k] + callers = counts.keys() + callers.sort() + for c in callers: + #file.write(" counts[%s] = %s\n" % (c, counts[c])) + t = ((counts[c],) + func_shorten(c)) + file.write(" %6d %s:%d(%s)\n" % t) + +shorten_list = [ + ( '/scons/SCons/', 1), + ( '/src/engine/SCons/', 1), + ( '/usr/lib/python', 0), +] + +def func_shorten(func_tuple): + f = func_tuple[0] + for t in shorten_list: + i = string.find(f, t[0]) + if i >= 0: + if t[1]: + i = i + len(t[0]) + f = f[i:] + break + return (f,)+func_tuple[1:] diff --git a/src/engine/SCons/Script/Main.py b/src/engine/SCons/Script/Main.py index f50273e..f66f214 100644 --- a/src/engine/SCons/Script/Main.py +++ b/src/engine/SCons/Script/Main.py @@ -1127,6 +1127,11 @@ def _main(args, parser): print "Memoizer (memory cache) hits and misses:" SCons.Memoize.Dump() + # Dump any caller counts. This is purely for internal debugging + # during development, so there's no need to control it with a + # --debug= option. + SCons.Debug.dump_caller_counts() + def _exec_main(): all_args = sys.argv[1:] try: |