GROOVY-10307: backport JMH benchmarks from master to Groovy 4#2393
Open
jamesfredley wants to merge 1 commit intoapache:GROOVY_4_0_Xfrom
Open
GROOVY-10307: backport JMH benchmarks from master to Groovy 4#2393jamesfredley wants to merge 1 commit intoapache:GROOVY_4_0_Xfrom
jamesfredley wants to merge 1 commit intoapache:GROOVY_4_0_Xfrom
Conversation
Backport JMH benchmarks for invokedynamic performance patterns and Grails-like workload simulations from master to the GROOVY_4_0_X branch. 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, and composite request-cycle patterns). Adapt DynamicDispatchBench for Groovy 4 compatibility: move classes using methodMissing/propertyMissing to package level since Groovy 4 does not support these on static inner classes. 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.
There was a problem hiding this comment.
Pull request overview
This PR backports a set of JMH microbenchmarks from master into the Groovy 4 branch to enable performance comparison testing, including Grails-like metaprogramming and invokedynamic invalidation scenarios, plus supporting build/CI wiring.
Changes:
- Adds new JMH benchmark suites under
org.apache.groovy.perfandorg.apache.groovy.perf.grailscovering closures, GStrings, operators, method/property dispatch, metaclass churn, categories, and workload simulations. - Updates performance Gradle build logic to allow toggling Groovy indy compilation via
-Pindy=...and improves task input/output tracking. - Introduces CI workflows to run JMH in indy and “classic” (non-indy) modes across benchmark suites.
Reviewed changes
Copilot reviewed 19 out of 19 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| subprojects/performance/src/jmh/groovy/org/apache/groovy/perf/grails/MetaclassVariationBench.groovy | New benchmark for per-instance EMC overhead and cross-type churn scenarios. |
| subprojects/performance/src/jmh/groovy/org/apache/groovy/perf/grails/MetaclassChangeBench.groovy | New benchmark suite focusing on metaclass modification impact on indy call sites. |
| subprojects/performance/src/jmh/groovy/org/apache/groovy/perf/grails/GrailsWorkloadBench.groovy | New workload-style benchmarks based on Grails-like collection/DSL patterns. |
| subprojects/performance/src/jmh/groovy/org/apache/groovy/perf/grails/GrailsLikePatternsBench.groovy | Composite Grails-like request/service/domain/builder patterns. |
| subprojects/performance/src/jmh/groovy/org/apache/groovy/perf/grails/DynamicDispatchBench.groovy | Benchmarks for methodMissing/propertyMissing/invokeMethod/Expando injection dispatch. |
| subprojects/performance/src/jmh/groovy/org/apache/groovy/perf/grails/CategoryBench.groovy | Category usage benchmarks measuring invalidation overhead patterns. |
| subprojects/performance/src/jmh/groovy/org/apache/groovy/perf/grails/CallSiteInvalidationBench.groovy | Focused SwitchPoint invalidation benchmarks (same-/cross-type). |
| subprojects/performance/src/jmh/groovy/org/apache/groovy/perf/RunnerRegistryBench.java | New benchmark for GroovyRunnerRegistry iterator performance. |
| subprojects/performance/src/jmh/groovy/org/apache/groovy/perf/PropertyAccessBench.groovy | Property access microbenchmarks (fields/getters/maps/chaining). |
| subprojects/performance/src/jmh/groovy/org/apache/groovy/perf/OperatorBench.groovy | Operator dispatch microbenchmarks (arithmetic, subscripts, comparisons, etc.). |
| subprojects/performance/src/jmh/groovy/org/apache/groovy/perf/MethodInvocationBench.groovy | Method invocation microbenchmarks (overloads, polymorphism, def-typed). |
| subprojects/performance/src/jmh/groovy/org/apache/groovy/perf/MetaclassBench.groovy | Benchmarks for call dispatch under ongoing metaclass changes. |
| subprojects/performance/src/jmh/groovy/org/apache/groovy/perf/LoopsBench.groovy | Loop pattern benchmarks (each vs method call vs closure reuse, etc.). |
| subprojects/performance/src/jmh/groovy/org/apache/groovy/perf/GroovyIdiomBench.groovy | Groovy idiom benchmarks (safe nav, spread-dot, elvis, with/tap, ranges, as). |
| subprojects/performance/src/jmh/groovy/org/apache/groovy/perf/GStringBench.groovy | GString interpolation/concat/toString benchmarks. |
| subprojects/performance/src/jmh/groovy/org/apache/groovy/perf/ClosureBench.groovy | Closure creation/reuse/currying/composition/trampoline/collection operation benchmarks. |
| build-logic/src/main/groovy/org.apache.groovy-performance.gradle | Adds -Pindy toggle and improves JMH task inputs/outputs. |
| .github/workflows/groovy-jmh.yml | New CI workflow to run JMH suites with indy enabled. |
| .github/workflows/groovy-jmh-classic.yml | New CI workflow to run JMH suites with indy disabled. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
subprojects/performance/src/jmh/groovy/org/apache/groovy/perf/OperatorBench.groovy
Show resolved
Hide resolved
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_4_0_X branch, enabling performance comparison testing on Groovy 4.
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 configurationCI 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 4 compatibility adaptation
DynamicDispatchBench: movedDynamicFinder,DynamicProperties, andMethodInterceptorfrom static inner classes to package-level classes because Groovy 4 does not supportmethodMissing/propertyMissingon static inner classesVerification
./gradlew :performance:jmhClasses(indy mode)./gradlew :performance:jmhClasses -Pindy=false(classic mode)