summaryrefslogtreecommitdiffstats
path: root/src/engine/SCons/Node
diff options
context:
space:
mode:
authorAlexey Klimkin <klimkin@gmail.com>2016-05-26 18:03:00 (GMT)
committerAlexey Klimkin <klimkin@gmail.com>2016-05-26 18:03:00 (GMT)
commit29a46d09fdb0bc3e8d7b18dca6ac8495e96c5eb4 (patch)
treec14eb845a9b25435b1c35633d0857017c2a26e2d /src/engine/SCons/Node
parentaa5a0468340338cc3423a06d6d55e1b52a713bc5 (diff)
downloadSCons-29a46d09fdb0bc3e8d7b18dca6ac8495e96c5eb4.zip
SCons-29a46d09fdb0bc3e8d7b18dca6ac8495e96c5eb4.tar.gz
SCons-29a46d09fdb0bc3e8d7b18dca6ac8495e96c5eb4.tar.bz2
Optimize implicit dependency scan
When calculating path, performance spent on two things: - Variable expansion, if CPPPATH contains any variables - CPPPATH flattening Use memoization to optimize PATH evaluation across all dependencies per node.
Diffstat (limited to 'src/engine/SCons/Node')
-rw-r--r--src/engine/SCons/Node/__init__.py22
1 files changed, 12 insertions, 10 deletions
diff --git a/src/engine/SCons/Node/__init__.py b/src/engine/SCons/Node/__init__.py
index 1a76b60..d3cea53 100644
--- a/src/engine/SCons/Node/__init__.py
+++ b/src/engine/SCons/Node/__init__.py
@@ -926,9 +926,9 @@ class Node(object):
scanner's recursive flag says that we should.
"""
nodes = [self]
- seen = {}
- seen[self] = 1
+ seen = set(nodes)
dependencies = []
+ path_memo = {}
root_node_scanner = self._get_scanner(env, initial_scanner, None, kw)
@@ -936,30 +936,32 @@ class Node(object):
node = nodes.pop(0)
scanner = node._get_scanner(env, initial_scanner, root_node_scanner, kw)
-
if not scanner:
continue
- path = path_func(scanner)
+ try:
+ path = path_memo[scanner]
+ except KeyError:
+ path = path_func(scanner)
+ path_memo[scanner] = path
included_deps = [x for x in node.get_found_includes(env, scanner, path) if x not in seen]
if included_deps:
dependencies.extend(included_deps)
- for dep in included_deps:
- seen[dep] = 1
+ seen.update(included_deps)
nodes.extend(scanner.recurse_nodes(included_deps))
return dependencies
def _get_scanner(self, env, initial_scanner, root_node_scanner, kw):
- if not initial_scanner:
+ if initial_scanner:
+ # handle explicit scanner case
+ scanner = initial_scanner.select(self)
+ else:
# handle implicit scanner case
scanner = self.get_env_scanner(env, kw)
if scanner:
scanner = scanner.select(self)
- else:
- # handle explicit scanner case
- scanner = initial_scanner.select(self)
if not scanner:
# no scanner could be found for the given node's scanner key;