Optimize reactor sort, model pool, and phase comparator performance - #12652
Draft
gnodet wants to merge 1 commit into
Draft
Optimize reactor sort, model pool, and phase comparator performance#12652gnodet wants to merge 1 commit into
gnodet wants to merge 1 commit into
Conversation
…mance JFR profiling of a 4,383-module reactor revealed three hotspots that together consume ~35% of CPU time during dependency resolution: 1. DefaultGraphBuilder: result.sort(comparing(sortedProjects::indexOf)) uses O(n) ArrayList.indexOf per comparison, causing O(n² log n) total MavenProject.equals calls (~230M for 4,383 modules). Replace with a HashMap<MavenProject, Integer> index built in O(n), reducing sort comparisons to O(1) each. Affects 3 call sites. 2. DefaultModelObjectPool.getPooledTypes(): re-parses a comma-separated property string into a new Stream → Set on every process() call. Cache the parsed Set at construction time. Also add hashCode fast-rejection to PoolKey.equals() to skip expensive deep equality when hashes differ. 3. DefaultModelObjectPool.PoolKey.dependencyHashCode(): Objects.hash() with 12 arguments allocates a new Object[12] on every call. Inline the hash computation to eliminate the varargs allocation. 4. PhaseComparator: List.indexOf() in compare() is O(n) per call. Pre-build a HashMap<String, Integer> in the constructor for O(1) phase index lookups. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
3 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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 useresult.sort(comparing(sortedProjects::indexOf))whereArrayList.indexOf()is O(n), causing O(n² log n) totalMavenProject.equals()calls (~230M for 4,383 modules). Replaced with aHashMap<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 newStream→Seton everyprocess()call (hundreds of thousands of times). Cached at construction time.PoolKey.dependencyHashCode()usesObjects.hash()with 12 arguments, allocating anew Object[12]on every call. Inlined the hash computation.PoolKey.equals()to skip expensive deep equality when hashes differ.PhaseComparator(~2% CPU):List.indexOf()incompare()is O(n) per call. Pre-built aHashMap<String, Integer>in the constructor for O(1) phase index lookups.JFR Profile (before these fixes)
MavenProject.equalsArrayList.indexOfinDefaultGraphBuildersortDefaultModelObjectPool$PoolKey.*Objects.hashvarargsDefaultDependencyManagementImporter.importManagementPhaseComparator.compareList.indexOfper comparisonComplexity reduction
DefaultGraphBuildersortDefaultModelObjectPool.process()PoolKey.dependencyHashCodePhaseComparator.compareTest plan
DefaultModelObjectPoolTestpassesmaven-impltest suite passesDefaultGraphBuilderTest(blocked by pre-existingProjectBuildLogAppendercompile error on master — unrelated to this PR)🤖 Generated with Claude Code