Skip to content

Commit 15cad14

Browse files
jamesfredleypaulk-asert
authored andcommitted
GROOVY-10307: backport JMH benchmarks from master to Groovy 5
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
1 parent c57c176 commit 15cad14

20 files changed

Lines changed: 4019 additions & 2 deletions
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
# Licensed to the Apache Software Foundation (ASF) under one or more
2+
# contributor license agreements. See the NOTICE file distributed with
3+
# this work for additional information regarding copyright ownership.
4+
# The ASF licenses this file to You under the Apache License, Version 2.0
5+
# (the "License"); you may not use this file except in compliance with
6+
# the License. You may obtain a copy of the License at
7+
#
8+
# http://www.apache.org/licenses/LICENSE-2.0
9+
#
10+
# Unless required by applicable law or agreed to in writing, software
11+
# distributed under the License is distributed on an "AS IS" BASIS,
12+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
# See the License for the specific language governing permissions and
14+
# limitations under the License.
15+
16+
name: jmh-classic
17+
18+
on: [push, pull_request]
19+
20+
permissions:
21+
contents: read
22+
23+
jobs:
24+
test:
25+
if: >-
26+
contains(github.event.head_commit.message || '', 'GROOVY-') ||
27+
contains(github.event.pull_request.title || '', 'GROOVY-')
28+
strategy:
29+
fail-fast: false
30+
matrix:
31+
include:
32+
- suite: bench
33+
pattern: '\\.bench\\.'
34+
- suite: core
35+
pattern: '\\.perf\\.[A-Z]'
36+
- suite: grails
37+
pattern: '\\.perf\\.grails\\.'
38+
runs-on: ubuntu-latest
39+
env:
40+
DEVELOCITY_ACCESS_KEY: ${{ secrets.DEVELOCITY_ACCESS_KEY }}
41+
steps:
42+
- uses: actions/checkout@v6
43+
- uses: actions/setup-java@v5
44+
with:
45+
distribution: 'zulu'
46+
java-version: 21
47+
check-latest: true
48+
- uses: gradle/actions/setup-gradle@0723195856401067f7a2779048b490ace7a47d7c # v5.0.2
49+
- name: JMH (${{ matrix.suite }} classic)
50+
run: ./gradlew perf:jmh -PbenchInclude=${{ matrix.pattern }} -Pindy=false
51+
timeout-minutes: 60
52+
- name: Rename JMH result file
53+
run: |
54+
mv subprojects/performance/build/results/jmh/results.txt \
55+
subprojects/performance/build/results/jmh/results-${{ matrix.suite }}.txt
56+
57+
- name: Upload reports-jmh-classic-${{ matrix.suite }}
58+
uses: actions/upload-artifact@v4
59+
with:
60+
name: reports-jmh-classic-${{ matrix.suite }}
61+
path: subprojects/performance/build/results/jmh/
62+

.github/workflows/groovy-jmh.yml

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
# Licensed to the Apache Software Foundation (ASF) under one or more
2+
# contributor license agreements. See the NOTICE file distributed with
3+
# this work for additional information regarding copyright ownership.
4+
# The ASF licenses this file to You under the Apache License, Version 2.0
5+
# (the "License"); you may not use this file except in compliance with
6+
# the License. You may obtain a copy of the License at
7+
#
8+
# http://www.apache.org/licenses/LICENSE-2.0
9+
#
10+
# Unless required by applicable law or agreed to in writing, software
11+
# distributed under the License is distributed on an "AS IS" BASIS,
12+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
# See the License for the specific language governing permissions and
14+
# limitations under the License.
15+
16+
name: jmh
17+
18+
on: [push, pull_request]
19+
20+
permissions:
21+
contents: read
22+
23+
jobs:
24+
test:
25+
if: >-
26+
contains(github.event.head_commit.message || '', 'GROOVY-') ||
27+
contains(github.event.pull_request.title || '', 'GROOVY-')
28+
strategy:
29+
fail-fast: false
30+
matrix:
31+
include:
32+
- suite: bench
33+
pattern: '\\.bench\\.'
34+
- suite: core
35+
pattern: '\\.perf\\.[A-Z]'
36+
- suite: grails
37+
pattern: '\\.perf\\.grails\\.'
38+
runs-on: ubuntu-latest
39+
env:
40+
DEVELOCITY_ACCESS_KEY: ${{ secrets.DEVELOCITY_ACCESS_KEY }}
41+
steps:
42+
- uses: actions/checkout@v6
43+
- uses: actions/setup-java@v5
44+
with:
45+
distribution: 'zulu'
46+
java-version: 21
47+
check-latest: true
48+
- uses: gradle/actions/setup-gradle@0723195856401067f7a2779048b490ace7a47d7c # v5.0.2
49+
- name: JMH (${{ matrix.suite }})
50+
run: ./gradlew perf:jmh -PbenchInclude=${{ matrix.pattern }}
51+
timeout-minutes: 60
52+
- name: Rename JMH result file
53+
run: |
54+
mv subprojects/performance/build/results/jmh/results.txt \
55+
subprojects/performance/build/results/jmh/results-${{ matrix.suite }}.txt
56+
57+
- name: Upload reports-jmh-${{ matrix.suite }}
58+
uses: actions/upload-artifact@v4
59+
with:
60+
name: reports-jmh-${{ matrix.suite }}
61+
path: subprojects/performance/build/results/jmh/
62+

build-logic/src/main/groovy/org.apache.groovy-performance.gradle

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,10 @@ repositories {
4444
dependencies {
4545
jmh project(':')
4646
testImplementation project(':')
47-
testImplementation "junit:junit:${versions.junit}"
47+
testImplementation "org.junit.jupiter:junit-jupiter-api:${versions.junit5}"
48+
testRuntimeOnly "org.junit.jupiter:junit-jupiter-engine:${versions.junit5}"
49+
testRuntimeOnly "org.junit.platform:junit-platform-launcher:${versions.junit5Platform}"
50+
4851
stats "org.apache.commons:commons-math3:${versions.commonsMath3}"
4952
}
5053

@@ -65,11 +68,16 @@ tasks.named('jmhClasses') {
6568
dependsOn tasks.named('clean')
6669
}
6770

71+
var indy = (project.findProperty('indy') ?: 'true').toBoolean()
72+
6873
tasks.named('compileJmhGroovy') {
6974
classpath += compileJmhJava.classpath
75+
groovyOptions.optimizationOptions.indy = indy
76+
inputs.property('indy', indy)
7077
}
7178

7279
tasks.register('displayJmhResults') {
80+
dependsOn('jmh')
7381
doLast {
7482
println layout.buildDirectory.file('results/jmh/results.txt').get().asFile.text
7583
}
@@ -80,3 +88,16 @@ tasks.register('performanceTests', PerformanceTestSummary)
8088
sonarqube {
8189
skipProject = true
8290
}
91+
92+
tasks.named('test') {
93+
useJUnitPlatform()
94+
}
95+
96+
tasks.named('jmh') {
97+
inputs.property('benchInclude', project.findProperty('benchInclude') ?: '')
98+
dependsOn tasks.named('jmhClasses')
99+
}
100+
101+
tasks.named('jmhJar') {
102+
from(sourceSets.jmh.output)
103+
}

0 commit comments

Comments
 (0)