Skip to content

perf(sorted_set): O(n+m) difference, intersection, symmetric_difference#3315

Open
bobzhang wants to merge 1 commit intomainfrom
hongbo/sorted-set-diff-intersect
Open

perf(sorted_set): O(n+m) difference, intersection, symmetric_difference#3315
bobzhang wants to merge 1 commit intomainfrom
hongbo/sorted-set-diff-intersect

Conversation

@bobzhang
Copy link
Copy Markdown
Contributor

@bobzhang bobzhang commented Mar 19, 2026

Summary

Replace O(n*log m) set operations with O(n+m) split-based divide-and-conquer, matching the approach used in immut/sorted_set.

Before

// O(n * log m) — iterates self, calls contains on src for each element
self.each(x => if !src.contains(x) { ret.add(x) })

After

// O(n + m) — split-based recursive merge
fn aux(a, b) {
  match (a, b) {
    (Some({ value: va, left: la, right: ra, .. }), _) => {
      let (lb, found, rb) = split_member(b, va)
      // recursively process left and right subtrees
    }
  }
}

For two 100K-element sets, this is approximately 17x faster (O(200K) vs O(100K * 17)).

Changes

  • Add split_member — like split but also returns whether the pivot was found
  • Add concat — joins two trees where all left elements < all right elements
  • Add remove_min — helper for concat
  • Rewrite difference, intersection, symmetric_difference using split-based approach
  • Remove TODO comment about symmetric_difference optimization

Test plan

  • All 48 sorted_set tests pass

🤖 Generated with Claude Code


Open with Devin

@coveralls
Copy link
Copy Markdown
Collaborator

coveralls commented Mar 19, 2026

Pull Request Test Coverage Report for Build 3091

Details

  • 53 of 62 (85.48%) changed or added relevant lines in 1 file are covered.
  • No unchanged relevant lines lost coverage.
  • Overall coverage decreased (-0.05%) to 95.668%

Changes Missing Coverage Covered Lines Changed/Added Lines %
sorted_set/set.mbt 53 62 85.48%
Totals Coverage Status
Change from base Build 3090: -0.05%
Covered Lines: 13823
Relevant Lines: 14449

💛 - Coveralls

Copy link
Copy Markdown

@devin-ai-integration devin-ai-integration bot left a comment

Choose a reason for hiding this comment

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

✅ Devin Review: No Issues Found

Devin Review analyzed this PR and found no potential bugs to report.

View in Devin Review to see 4 additional findings.

Open in Devin Review

@bobzhang bobzhang force-pushed the hongbo/sorted-set-diff-intersect branch from 6e62af2 to 281c2bf Compare March 19, 2026 23:50
@bobzhang bobzhang force-pushed the hongbo/sorted-set-diff-intersect branch 2 times, most recently from 645de7f to aa3d5e5 Compare March 20, 2026 01:10
…, symmetric_difference

Replace O(n*log m) implementations that iterate + contains with
split-based divide-and-conquer approach matching immut/sorted_set.

Before: self.each(x => if !src.contains(x) { ret.add(x) })
  - O(n * log m) for each operation

After: split_member-based recursive merge
  - O(n + m) using the same algorithm as immut/sorted_set

Also removes the TODO comment about symmetric_difference optimization.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@bobzhang bobzhang force-pushed the hongbo/sorted-set-diff-intersect branch from aa3d5e5 to a6ab4bf Compare March 20, 2026 04:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants