Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

@adwait1290
Copy link
Contributor

@adwait1290 adwait1290 commented Dec 8, 2025

Current Behavior

The hasPath function in graph.ts uses an array with indexOf() for tracking visited nodes during recursive graph traversal:

function hasPath(graph, target, node, visited: string[]) {
  for (let d of graph.dependencies[node] || []) {
    if (visited.indexOf(d.target) > -1) continue;  // O(n) lookup
    visited.push(d.target);
    // recursive call...
  }
}

This results in O(n) lookups per node visited, making worst-case traversal O(n²).

Expected Behavior

Use Set for O(1) visited node tracking:

function hasPath(graph, target, node, visited: Set<string>) {
  for (const d of graph.dependencies[node] || []) {
    if (visited.has(d.target)) continue;  // O(1) lookup
    visited.add(d.target);
    // recursive call...
  }
}

Performance Impact

Before (Array + indexOf):              After (Set + has):
┌─────────────────────────┐           ┌─────────────────────────┐
│   hasPath() called      │           │   hasPath() called      │
└───────────┬─────────────┘           └───────────┬─────────────┘
            │                                     │
            ▼                                     ▼
┌─────────────────────────┐           ┌─────────────────────────┐
│ visited.indexOf(target) │           │  visited.has(target)    │
│      O(n) lookup        │           │      O(1) lookup        │
└───────────┬─────────────┘           └───────────┬─────────────┘
            │                                     │
            ▼                                     ▼
┌─────────────────────────┐           ┌─────────────────────────┐
│   visited.push(target)  │           │   visited.add(target)   │
│        O(1)             │           │        O(1)             │
└───────────┬─────────────┘           └───────────┬─────────────┘
            │                                     │
            ▼                                     ▼
    Complexity: O(n²)                     Complexity: O(n)
    for full traversal                    for full traversal

Example with 500 nodes:

  • Before: 500 nodes × avg 250 indexOf lookups = ~125,000 comparisons
  • After: 500 nodes × 1 Set lookup each = 500 operations

Why Accept This PR

  1. Zero risk: Same semantics, just faster data structure
  2. Standard pattern: Set is the idiomatic choice for visited tracking in graph algorithms
  3. Measurable impact: Graph filtering with --focus flag will be significantly faster on large monorepos

Related Issue(s)

Contributes to #32265

Merge Dependencies

This PR has no dependencies and can be merged independently.


The hasPath function used an array with indexOf() for cycle detection
during graph traversal. This is O(n) per lookup, making the overall
traversal O(n²) in the worst case.

Changed to use Set with has() for O(1) lookups, reducing complexity
to O(n) for graph path finding operations.
@adwait1290 adwait1290 requested a review from a team as a code owner December 8, 2025 07:09
@adwait1290 adwait1290 requested a review from Cammisuli December 8, 2025 07:09
@netlify
Copy link

netlify bot commented Dec 8, 2025

👷 Deploy request for nx-docs pending review.

Visit the deploys page to approve it

Name Link
🔨 Latest commit 7af913e

@chatgpt-codex-connector
Copy link

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@vercel
Copy link

vercel bot commented Dec 8, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Preview Updated (UTC)
nx-dev Ready Ready Preview Dec 8, 2025 6:48pm

@nx-cloud
Copy link
Contributor

nx-cloud bot commented Dec 8, 2025

View your CI Pipeline Execution ↗ for commit 7af913e

Command Status Duration Result
nx affected --targets=lint,test,test-kt,build,e... ✅ Succeeded 11m 3s View ↗
nx run-many -t check-imports check-lock-files c... ✅ Succeeded 2m 42s View ↗
nx-cloud record -- nx-cloud conformance:check ✅ Succeeded 12s View ↗
nx-cloud record -- nx format:check ✅ Succeeded 2s View ↗
nx-cloud record -- nx sync:check ✅ Succeeded <1s View ↗

☁️ Nx Cloud last updated this comment at 2025-12-08 18:57:58 UTC

@FrozenPandaz FrozenPandaz changed the title perf(graph): use Set for O(1) visited node lookup in hasPath fix(graph): use Set for O(1) visited node lookup in hasPath Dec 8, 2025
@FrozenPandaz FrozenPandaz changed the title fix(graph): use Set for O(1) visited node lookup in hasPath fix(core): use Set for O(1) visited node lookup in hasPath Dec 8, 2025
Copy link
Contributor

@nx-cloud nx-cloud bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nx Cloud has identified a flaky task in your failed CI:

Since the failure was identified as flaky, the solution is to rerun CI. Because this branch comes from a fork, it is not possible for us to push directly, but you can rerun by pushing an empty commit:

git commit --allow-empty -m "chore: trigger rerun"
git push

Nx Cloud View detailed reasoning in Nx Cloud ↗


🎓 Learn more about Self-Healing CI on nx.dev

@adwait1290 adwait1290 changed the title fix(core): use Set for O(1) visited node lookup in hasPath perf(graph): use Set for O(1) visited node lookup in hasPath Dec 8, 2025
@FrozenPandaz FrozenPandaz changed the title perf(graph): use Set for O(1) visited node lookup in hasPath fix(core): use Set for O(1) visited node lookup in hasPath Dec 8, 2025
Copy link
Collaborator

@FrozenPandaz FrozenPandaz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for your contribution! LGTM 🎉

@FrozenPandaz FrozenPandaz merged commit 300493e into nrwl:master Dec 8, 2025
16 of 18 checks passed
@github-actions
Copy link
Contributor

This pull request has already been merged/closed. If you experience issues related to these changes, please open a new issue referencing this pull request.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Dec 14, 2025
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants