diff options
author | Tomasz Śniatowski <tsniatowski@vewd.com> | 2021-02-15 12:06:30 (GMT) |
---|---|---|
committer | Tomasz Śniatowski <tsniatowski@vewd.com> | 2021-02-22 22:48:58 (GMT) |
commit | 6c89e596eef50a4aa53f3cdc0f40a7071638769f (patch) | |
tree | 7e82b08661dce413d9e18fbb82ac0dd5c3bdaf9b /src | |
parent | b94a891ac9fcd0cee80652197c03633d752ad068 (diff) | |
download | Ninja-6c89e596eef50a4aa53f3cdc0f40a7071638769f.zip Ninja-6c89e596eef50a4aa53f3cdc0f40a7071638769f.tar.gz Ninja-6c89e596eef50a4aa53f3cdc0f40a7071638769f.tar.bz2 |
missingdeps: use nested maps for edge adjacency cache
In my tests, nested maps outperform a large map of pairs by 10-20% on a
sample Chromium missingdeps run, and are arguably simpler due to fewer
ifdefs needed.
Diffstat (limited to 'src')
-rw-r--r-- | src/missing_deps.cc | 15 | ||||
-rw-r--r-- | src/missing_deps.h | 34 |
2 files changed, 15 insertions, 34 deletions
diff --git a/src/missing_deps.cc b/src/missing_deps.cc index adce2d2..eaa3f73 100644 --- a/src/missing_deps.cc +++ b/src/missing_deps.cc @@ -172,10 +172,15 @@ void MissingDependencyScanner::PrintStats() { } bool MissingDependencyScanner::PathExistsBetween(Edge* from, Edge* to) { - EdgePair key(from, to); - EdgeAdjacencyMap::iterator it = edge_adjacency_map_.find(key); - if (it != edge_adjacency_map_.end()) - return it->second; + AdjacencyMap::iterator it = adjacency_map_.find(from); + if (it != adjacency_map_.end()) { + InnerAdjacencyMap::iterator inner_it = it->second.find(to); + if (inner_it != it->second.end()) { + return inner_it->second; + } + } else { + it = adjacency_map_.insert(std::make_pair(from, InnerAdjacencyMap())).first; + } bool found = false; for (size_t i = 0; i < to->inputs_.size(); ++i) { Edge* e = to->inputs_[i]->in_edge(); @@ -184,6 +189,6 @@ bool MissingDependencyScanner::PathExistsBetween(Edge* from, Edge* to) { break; } } - edge_adjacency_map_.insert(std::make_pair(key, found)); + it->second.insert(std::make_pair(to, found)); return found; } diff --git a/src/missing_deps.h b/src/missing_deps.h index 211a865..ae57074 100644 --- a/src/missing_deps.h +++ b/src/missing_deps.h @@ -44,32 +44,6 @@ class MissingDependencyPrinter : public MissingDependencyScannerDelegate { int generator_rules); }; -struct EdgePair { - EdgePair(Edge* from, Edge* to) : from_(from), to_(to) {} - bool operator==(const EdgePair& other) const { - return from_ == other.from_ && to_ == other.to_; - } - bool operator<(const EdgePair& other) const { - return (from_ < other.from_) || - ((from_ == other.from_) && (to_ < other.to_)); - } - Edge* from_; - Edge* to_; -}; - -#if __cplusplus >= 201103L -namespace std { -template <> -struct hash<EdgePair> { - size_t operator()(const EdgePair& k) const { - uintptr_t uint_from = uintptr_t(k.from_); - uintptr_t uint_to = uintptr_t(k.to_); - return hash<uintptr_t>()(uint_from ^ (uint_to >> 3)); - } -}; -} // namespace std -#endif // __cplusplus >= 201103L - struct MissingDependencyScanner { public: MissingDependencyScanner(MissingDependencyScannerDelegate* delegate, @@ -95,11 +69,13 @@ struct MissingDependencyScanner { private: #if __cplusplus >= 201103L - using EdgeAdjacencyMap = std::unordered_map<EdgePair, bool>; + using InnerAdjacencyMap = std::unordered_map<Edge*, bool>; + using AdjacencyMap = std::unordered_map<Edge*, InnerAdjacencyMap>; #else - typedef std::map<EdgePair, bool> EdgeAdjacencyMap; + typedef std::map<Edge*, bool> InnerAdjacencyMap; + typedef std::map<Edge*, InnerAdjacencyMap> AdjacencyMap; #endif - EdgeAdjacencyMap edge_adjacency_map_; + AdjacencyMap adjacency_map_; }; #endif // NINJA_MISSING_DEPS_H_ |