summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorSteven Knight <knight@baldmt.com>2005-03-04 21:27:30 (GMT)
committerSteven Knight <knight@baldmt.com>2005-03-04 21:27:30 (GMT)
commit213996506374ad40fc7ee4949e2be3790ead99d9 (patch)
treee994d5104a10b6dd448afee90cd411931cf6670a /src
parent3bf4475522d2a24910b147a607dcd9f0d980097f (diff)
downloadSCons-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.py39
-rw-r--r--src/engine/SCons/Debug.py48
-rw-r--r--src/engine/SCons/Script/Main.py5
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: