GROOVY-10307: backport JMH benchmarks from master to Groovy 5#2494
Open
jamesfredley wants to merge 1 commit intoapache:GROOVY_5_0_Xfrom
Open
GROOVY-10307: backport JMH benchmarks from master to Groovy 5#2494jamesfredley wants to merge 1 commit intoapache:GROOVY_5_0_Xfrom
jamesfredley wants to merge 1 commit intoapache:GROOVY_5_0_Xfrom
Conversation
There was a problem hiding this comment.
Pull request overview
Backports the GROOVY-10307 JMH benchmark suite (core Groovy + Grails-like patterns) onto the Groovy 5 branch and wires up build/CI support to run the benchmarks in indy vs classic mode for performance comparisons.
Changes:
- Adds new JMH benchmarks under
subprojects/performance/src/jmh/groovycovering invokedynamic/metaclass invalidation patterns and common Groovy idioms. - Updates the performance build logic to support
-Pindy=true|false, JMH input tracking, and migrates the performance test setup from JUnit 4 to JUnit 5. - Adds GitHub Actions workflows to run the JMH suites in indy and classic modes.
Reviewed changes
Copilot reviewed 20 out of 20 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| subprojects/performance/src/test/groovy/DummyTest.groovy | Switches the placeholder test to JUnit Jupiter. |
| build-logic/src/main/groovy/org.apache.groovy-performance.gradle | Adds JUnit 5 deps, indy toggle for JMH Groovy compilation, and JMH task input/output wiring. |
| .github/workflows/groovy-jmh.yml | New CI workflow to run JMH suites with indy enabled and upload results. |
| .github/workflows/groovy-jmh-classic.yml | New CI workflow to run JMH suites with indy disabled and upload results. |
| subprojects/performance/src/jmh/groovy/org/apache/groovy/perf/ClosureBench.groovy | Adds closure-focused microbenchmarks. |
| subprojects/performance/src/jmh/groovy/org/apache/groovy/perf/GStringBench.groovy | Adds GString creation/interpolation benchmarks. |
| subprojects/performance/src/jmh/groovy/org/apache/groovy/perf/GroovyIdiomBench.groovy | Adds idiomatic Groovy feature benchmarks (safe-nav, elvis, spread, etc.). |
| subprojects/performance/src/jmh/groovy/org/apache/groovy/perf/LoopsBench.groovy | Adds loop/iteration pattern benchmarks. |
| subprojects/performance/src/jmh/groovy/org/apache/groovy/perf/MetaclassBench.groovy | Adds metaclass-change invalidation benchmark. |
| subprojects/performance/src/jmh/groovy/org/apache/groovy/perf/MethodInvocationBench.groovy | Adds method invocation/dispatch benchmarks. |
| subprojects/performance/src/jmh/groovy/org/apache/groovy/perf/OperatorBench.groovy | Adds operator dispatch benchmarks. |
| subprojects/performance/src/jmh/groovy/org/apache/groovy/perf/PropertyAccessBench.groovy | Adds property access pattern benchmarks. |
| subprojects/performance/src/jmh/groovy/org/apache/groovy/perf/RunnerRegistryBench.java | Adds GroovyRunnerRegistry iterator benchmark. |
| subprojects/performance/src/jmh/groovy/org/apache/groovy/perf/grails/CallSiteInvalidationBench.groovy | Adds SwitchPoint invalidation workload benchmarks. |
| subprojects/performance/src/jmh/groovy/org/apache/groovy/perf/grails/CategoryBench.groovy | Adds category-scope invalidation benchmarks. |
| subprojects/performance/src/jmh/groovy/org/apache/groovy/perf/grails/DynamicDispatchBench.groovy | Adds methodMissing/propertyMissing/invokeMethod dispatch benchmarks (Groovy 5-compatible layout). |
| subprojects/performance/src/jmh/groovy/org/apache/groovy/perf/grails/GrailsLikePatternsBench.groovy | Adds composite “Grails-like” pattern workloads. |
| subprojects/performance/src/jmh/groovy/org/apache/groovy/perf/grails/GrailsWorkloadBench.groovy | Adds workload-style Grails demo-app pattern benchmarks. |
| subprojects/performance/src/jmh/groovy/org/apache/groovy/perf/grails/MetaclassChangeBench.groovy | Adds metaclass churn / invalidation cascade benchmarks. |
| subprojects/performance/src/jmh/groovy/org/apache/groovy/perf/grails/MetaclassVariationBench.groovy | Adds per-instance ExpandoMetaClass variation benchmarks. |
Backport JMH benchmarks for invokedynamic performance patterns and Grails-like workload simulations from master to the GROOVY_5_0_X branch, enabling performance comparison testing on Groovy 5. New benchmarks cover core Groovy performance (closures, GStrings, method invocation, operators, property access, loops, metaclass overhead) and Grails-specific patterns (call site invalidation, categories, dynamic dispatch, metaclass changes, per-instance metaclass variation, workload simulation, composite request-cycle patterns, and SwitchPoint invalidation). Adapt DynamicDispatchBench for Groovy 5 compatibility: move classes using methodMissing/propertyMissing to package level since Groovy 5 does not support these on static inner classes. Migrate the performance subproject from JUnit 4 to JUnit 5 (versions.junit5 / versions.junit5Platform) to match the JUnit setup used elsewhere on GROOVY_5_0_X. Update the performance gradle plugin to support indy/classic mode selection for JMH compilation. Add CI workflows for running JMH benchmarks in both indy and classic modes. Assisted-by: claude-code:claude-4.6-opus
91b08bb to
b503135
Compare
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## GROOVY_5_0_X #2494 +/- ##
=================================================
Coverage 67.1396% 67.1396%
+ Complexity 29435 29434 -1
=================================================
Files 1382 1382
Lines 116797 116797
Branches 20481 20481
=================================================
Hits 78417 78417
+ Misses 31889 31888 -1
- Partials 6491 6492 +1 🚀 New features to boost your workflow:
|
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
Backport JMH benchmarks for invokedynamic performance patterns and Grails-like workload simulations from master to the GROOVY_5_0_X branch, enabling performance comparison testing on Groovy 5. Companion to #2393 (which targets GROOVY_4_0_X).
The benchmark sources are taken from the latest master content (15+ follow-up fixes after the original GROOVY-10307 commit, including the SwitchPoint invalidation regression suite and Copilot review feedback).
Changes
New JMH benchmarks (16 files)
Core Groovy performance (
org.apache.groovy.perf):ClosureBench- closure creation, reuse, capture, delegation, nesting, currying, composition, trampoline, collection operationsGStringBench- GString interpolation, concatenation, lazy evaluationGroovyIdiomBench- Groovy idioms (safe navigation, elvis, spread, with/tap, destructuring)LoopsBench- for/while/each/times/upto loop patternsMetaclassBench- dynamic method dispatch overhead with metaclass changesMethodInvocationBench- method dispatch (instance, static, overloaded, polymorphic, interface, dynamic)OperatorBench- operator overloading, comparisons, range operationsPropertyAccessBench- property get/set patterns (direct, dynamic, nested)RunnerRegistryBench- GroovyRunnerRegistry iterator performanceGrails-like patterns (
org.apache.groovy.perf.grails):CallSiteInvalidationBench- SwitchPoint invalidation overhead for cross-type and same-type metaclass changesCategoryBench- category usage patterns (single, nested, simultaneous, shadowing)DynamicDispatchBench- methodMissing, propertyMissing, invokeMethod, ExpandoMetaClass injectionGrailsLikePatternsBench- composite patterns (service chains, controller actions, domain validation, config DSL, markup builder, full request cycle)GrailsWorkloadBench- collection closure chains, spread operator, nested closure delegation, GString interpolation, project metrics aggregationMetaclassChangeBench- metaclass modification impact (expando additions, replacements, multi-class cascade, burst/steady-state, closure dispatch)MetaclassVariationBench- per-instance ExpandoMetaClass overhead (GORM domain class enhancement pattern)Build changes
org.apache.groovy-performance.gradleto supportindyproperty for toggling invokedynamic mode in JMH compilation (-Pindy=true|false, defaults to true)jmhtask input tracking andjmhJaroutput configurationversions.junit5/versions.junit5Platformsince GROOVY_5_0_X does not yet definejunit6)DummyTest.groovyto useorg.junit.jupiter.api.TestCI workflows
groovy-jmh.yml- runs JMH benchmarks with invokedynamic enabled (matrix: bench, core, grails suites)groovy-jmh-classic.yml- runs JMH benchmarks with classic (non-indy) bytecodeGroovy 5 compatibility adaptation
DynamicDispatchBench: movedDynamicFinder,DynamicProperties, andMethodInterceptorfrom static inner classes to package-level classes because Groovy 5 does not supportmethodMissing/propertyMissingon static inner classes (same adaptation as GROOVY-10307: backport JMH benchmarks from master to Groovy 4 #2393, since the compiler restriction applies to both Groovy 4 and Groovy 5; master allows this on Groovy 6).Verification
./gradlew :performance:jmhClasses(indy mode) - BUILD SUCCESSFUL./gradlew :performance:jmhClasses -Pindy=false(classic mode) - BUILD SUCCESSFUL./gradlew :performance:jmh -PbenchInclude=GroovyIdiomBench.elvis- 3 elvis benchmarks completed successfully producing valid JMH output./gradlew :performance:test- BUILD SUCCESSFUL (verifies the JUnit 5 migration)