You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@maven.apache.org by "gnodet (via GitHub)" <gi...@apache.org> on 2026/07/31 21:52:59 UTC

[PR] Optimize reactor sort, model pool, and phase comparator performance [maven]

gnodet opened a new pull request, #12652:
URL: https://github.com/apache/maven/pull/12652

   ## Summary
   
   JFR profiling of a 4,383-module reactor build revealed three hotspots that together consume ~35% of CPU time. All three share the same root cause: **O(n) linear scans used inside tight loops or comparators**.
   
   ### Fixes
   
   - **`DefaultGraphBuilder`** (23.5% CPU): Three call sites use `result.sort(comparing(sortedProjects::indexOf))` where `ArrayList.indexOf()` is O(n), causing **O(n² log n)** total `MavenProject.equals()` calls (~230M for 4,383 modules). Replaced with a `HashMap<MavenProject, Integer>` index built in O(n), reducing each sort comparison to O(1).
   
   - **`DefaultModelObjectPool`** (~8% CPU, ~2.4 GB allocation pressure):
     - `getPooledTypes()` re-parses a comma-separated property string into a new `Stream` → `Set` **on every `process()` call** (hundreds of thousands of times). Cached at construction time.
     - `PoolKey.dependencyHashCode()` uses `Objects.hash()` with 12 arguments, allocating a `new Object[12]` on every call. Inlined the hash computation.
     - Added hashCode fast-rejection to `PoolKey.equals()` to skip expensive deep equality when hashes differ.
   
   - **`PhaseComparator`** (~2% CPU): `List.indexOf()` in `compare()` is O(n) per call. Pre-built a `HashMap<String, Integer>` in the constructor for O(1) phase index lookups.
   
   ### JFR Profile (before these fixes)
   
   | Rank | Method | CPU % | Root Cause |
   |------|--------|------:|------------|
   | 1 | `MavenProject.equals` | 23.5% | Called from `ArrayList.indexOf` in `DefaultGraphBuilder` sort |
   | 2 | `DefaultModelObjectPool$PoolKey.*` | ~8% | Stream re-parse + `Objects.hash` varargs |
   | 3 | `DefaultDependencyManagementImporter.importManagement` | 5.8% | (not addressed — model-level, not a data-structure issue) |
   | 4 | `PhaseComparator.compare` | ~2% | `List.indexOf` per comparison |
   
   ### Complexity reduction
   
   | Component | Before | After |
   |-----------|--------|-------|
   | `DefaultGraphBuilder` sort | O(n² log n) | O(n log n) |
   | `DefaultModelObjectPool.process()` | O(k) stream + alloc per call | O(1) Set.contains |
   | `PoolKey.dependencyHashCode` | 1 Object[12] alloc per call | 0 allocations |
   | `PhaseComparator.compare` | O(n) per comparison | O(1) per comparison |
   
   ## Test plan
   
   - [x] `DefaultModelObjectPoolTest` passes
   - [x] Full `maven-impl` test suite passes
   - [ ] `DefaultGraphBuilderTest` (blocked by pre-existing `ProjectBuildLogAppender` compile error on master — unrelated to this PR)
   - [ ] CI validation
   
   🤖 Generated with [Claude Code](https://claude.com/claude-code)


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@maven.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


Re: [PR] Optimize reactor sort, model pool, and phase comparator performance [maven]

Posted by "gnodet (via GitHub)" <gi...@apache.org>.
gnodet merged PR #12652:
URL: https://github.com/apache/maven/pull/12652


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@maven.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org