Skip to content

Avoid quadratic removeIf in JsonArray list views - #3115

Open
ishu7w wants to merge 3 commits into
google:mainfrom
ishu7w:codex/optimize-json-array-remove-if
Open

Avoid quadratic removeIf in JsonArray list views#3115
ishu7w wants to merge 3 commits into
google:mainfrom
ishu7w:codex/optimize-json-array-remove-if

Conversation

@ishu7w

@ishu7w ishu7w commented Sep 7, 2026

Copy link
Copy Markdown

Purpose

Avoid quadratic time when removing many elements through JsonArray.asList().removeIf(...).

Description

NonNullElementWrapperList inherits Collection.removeIf, which removes matching elements through the iterator. Each removal shifts the tail of the backing ArrayList. Filtering out a large fraction of an array therefore repeatedly copies the remaining elements.

Delegate removeIf to the backing ArrayList so it uses bulk removal, consistent with the existing removeAll and retainAll overrides. No dependency or public API is added.

The tests cover duplicate matches, JSON nulls, remaining element order, all/no matches, empty arrays, null predicates, and updates to the original JsonArray.

This also follows ArrayList behavior if the predicate throws: the operation may leave the list unchanged instead of partially filtered. The Collection contract does not guarantee a particular partial result on exception.

Validation

  • Java 21: mvn -B -ntp clean verify javadoc:jar passed across all eight modules.
  • Test reports: 4,868 tests, 21 skipped, zero failures or errors.
  • Focused JsonArrayAsListTest and JsonArrayAsListSuiteTest: 422 tests passed.

A local microbenchmark compiled the wrapper source before and after the change, populated an ArrayList<Integer> with consecutive integers, and timed new NonNullElementWrapperList<>(backing).removeIf(value -> (value & 1) == 0). Array construction was outside the timed interval. After ten 10,000-element warmups, medians of seven samples were:

Elements Before After
50,000 74.449 ms 0.604 ms
100,000 335.909 ms 0.479 ms
200,000 1388.171 ms 0.778 ms

These are illustrative single-machine measurements, not a JMH benchmark or an end-to-end application speed guarantee. The added functional tests verify behavior; they do not use timing assertions.

Checklist

  • Google Java Style checks pass.
  • Unit tests use Truth and JUnit 4, with no new JUnit 3 features.
  • mvn clean verify javadoc:jar passes.
  • Public API validation/Javadoc/@since: not applicable; no new public API.

AI assistance

Codex identified the performance issue, prepared the implementation and tests, ran local validation, and drafted this description.

Delegate removeIf to the backing ArrayList bulk-removal implementation.
Cover duplicate matches, JSON nulls, preserved order, empty arrays, and null predicates.
@google-cla

google-cla Bot commented Sep 7, 2026

Copy link
Copy Markdown

Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

View this failed invocation of the CLA check for more information.

For the most up to date status, view the checks section at the bottom of the pull request.

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.

1 participant