Skip to content

Fix HashSetAssert contains/containsAll O(n²) on large sets - #4355

Open
kalayciburak wants to merge 1 commit into
assertj:mainfrom
kalayciburak:fix/4233-hashset-contains-performance
Open

kalayciburak wants to merge 1 commit into
assertj:mainfrom
kalayciburak:fix/4233-hashset-contains-performance

Conversation

@kalayciburak

Copy link
Copy Markdown

Summary

assertThat(hashSet).contains(...) / .containsAll(...) scanned the whole set for every checked element, so both were O(n²) — containsAll of 50k elements against a 100k HashSet took several seconds (#4233).

InHashSetComparisonStrategy already holds the set under test, and HashSet#contains answers membership in O(1) via hashCode. Two small changes restore that:

  • HashSetAssert.InHashSetComparisonStrategy#iterableContains — when the iterable being checked is the set under test, return originalSet.contains(value) only (skip the redundant linear scan).
  • Iterables#assertContainsAll — reuse ensureActualCanBeReadMultipleTimes like assertContains so a Collection actual keeps its identity; the previous newArrayList(actual) copy forced the slow scan path for every element.

When the iterable is a different collection (e.g. after intermediate processing), behavior is unchanged: still originalSet.contains(value) && super.iterableContains(...).

Fixes #4233

Test plan

  • HashSetAssert_contains_performance_Test (RED→GREEN; 100k/50k under 2s timeout)
  • org.assertj.core.api.hashset.** — 110 tests GREEN
  • ./mvnw -pl assertj-core spotless:apply license:format

When checking membership against the HashSet under test, use
HashSet#contains (O(1)) instead of also scanning with
StandardComparisonStrategy. Align assertContainsAll with
assertContains so Collection actuals keep their identity for
strategy-backed lookups.

Fixes assertj#4233

This branch has not been deployed

No deployments
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.

Slow performance of contains / containsAll with large HashSet instances

1 participant