Skip to content

Commit

Permalink
2023: switch dfs to be non-recursive
Browse files Browse the repository at this point in the history
The perf stack traces for the recursive version were absolutely awful.
  • Loading branch information
yut23 committed Jan 26, 2024
1 parent 53bddc5 commit 9128614
Showing 1 changed file with 11 additions and 16 deletions.
27 changes: 11 additions & 16 deletions 2023/src/graph_traversal.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,15 @@
#define GRAPH_TRAVERSAL_HPP_56T9ZURK

#include "util/concepts.hpp"
#include <algorithm> // for reverse
#include <algorithm> // for min, reverse
#include <concepts> // for same_as, integral
#include <functional> // for function, greater
#include <map> // for map
#include <queue> // for priority_queue
#include <set> // for set
#include <stack> // for stack
#include <stdexcept> // for invalid_argument
#include <tuple> // for tuple
#include <type_traits> // for conditional_t // IWYU pragma: export
#include <unordered_map> // for unordered_map
#include <unordered_set> // for unordered_set
Expand Down Expand Up @@ -165,36 +166,30 @@ template <bool use_seen = true, class Key,
detail::VisitWithParent<Key> VisitWithParent>
int dfs(const Key &source, GetNeighbors &&get_neighbors, IsTarget &&is_target,
VisitWithParent &&visit_with_parent) {
std::stack<std::tuple<Key, Key, int>> stack{};
stack.emplace(source, source, 0);
detail::maybe_unordered_set<Key> seen{};

auto helper = [&seen, &get_neighbors, &is_target,
&visit_with_parent](const Key &key, int depth,
const Key &parent, const auto &rec) {
while (!stack.empty()) {
const auto [key, parent, depth] = std::move(stack.top());
stack.pop();
visit_with_parent(key, parent, depth);
if (is_target(key)) {
return depth;
return stack.size() - 1;
}
if constexpr (use_seen) {
seen.insert(key);
} else {
// suppress unused lambda capture warning
(void)seen;
}
for (const Key &neighbor : get_neighbors(key)) {
if constexpr (use_seen) {
if (seen.contains(neighbor)) {
continue;
}
}
int result = rec(neighbor, depth + 1, key, rec);
if (result != -1) {
return result;
}
stack.emplace(neighbor, key, depth + 1);
}
return -1;
};

return helper(source, 0, source, helper);
}
return -1;
}

template <bool use_seen = true, class Key,
Expand Down

0 comments on commit 9128614

Please sign in to comment.