@@ -2,17 +2,22 @@ plugins {
22 id(" smithy-java.java-conventions" )
33 id(" com.gradleup.shadow" )
44 id(" smithy-java.jmh-conventions" )
5- id(" software.amazon.smithy.gradle.smithy-base " )
5+ id(" software.amazon.smithy.java. gradle.smithy-java " )
66}
77
88description = " Serde (serialization/deserialization) microbenchmarks for smithy-java codecs."
99
10- // Not published. No `smithy-java.module-conventions`, no publishing, no BOM entry.
10+ smithyJava {
11+ projections.addAll(
12+ " aws-json-rpc-1-0-client" ,
13+ " aws-query-client" ,
14+ " rest-json-client" ,
15+ " rest-xml-client" ,
16+ " rpc-v2-cbor-client" ,
17+ )
18+ }
1119
1220// Benchmarks intentionally target JDK 25 (the rest of smithy-java targets 21).
13- // Performance measurements should reflect the latest JIT/runtime improvements
14- // available to consumers; the runtime deps were compiled for 21 but run fine
15- // on a newer JVM.
1621java {
1722 toolchain {
1823 languageVersion = JavaLanguageVersion .of(25 )
@@ -24,33 +29,18 @@ tasks.withType<JavaCompile>().configureEach {
2429}
2530
2631dependencies {
27- // Smithy traits needed at build time (smithy-build) and at runtime (when
28- // BenchmarkTestCases loads the model). The jmh configuration extends
29- // implementation, so these are available to both.
3032 implementation(libs.smithy.model)
3133 implementation(libs.smithy.aws.traits)
3234 implementation(libs.smithy.protocol.traits)
3335 implementation(libs.smithy.protocol.test.traits)
3436 implementation(libs.smithy.utils)
3537
36- // The Smithy Java codegen plugin produces typed shape classes plus
37- // ApiOperation classes per service (see `smithy-build.json`). The
38- // client-core dep is required because the generated client classes
39- // reference it.
40- smithyBuild(project(" :codegen:codegen-plugin" ))
41- smithyBuild(project(" :client:client-core" ))
42-
43- // smithy-java runtime stack — what we are benchmarking.
44- jmh(project(" :core" ))
4538 jmh(project(" :io" ))
4639 jmh(project(" :logging" ))
4740 jmh(project(" :codecs:json-codec" , configuration = " shadow" ))
4841 jmh(project(" :codecs:cbor-codec" ))
4942 jmh(project(" :codecs:xml-codec" ))
5043
51- // Client protocols — every benchmark drives the corresponding
52- // ClientProtocol#createRequest / #deserializeResponse, mirroring the
53- // reference implementation's protocol-level entry points.
5444 jmh(project(" :client:client-core" ))
5545 jmh(project(" :client:client-http" ))
5646 jmh(project(" :client:client-http-binding" ))
@@ -60,7 +50,6 @@ dependencies {
6050 jmh(project(" :aws:client:aws-client-restjson" ))
6151 jmh(project(" :aws:client:aws-client-restxml" ))
6252
63- // Protocol test document for converting test case params into typed shapes.
6453 jmh(project(" :protocol-test-harness" ))
6554
6655 // Dynamic-client path: build the ApiOperation + input from the runtime
@@ -69,20 +58,14 @@ dependencies {
6958 jmh(project(" :dynamic-schemas" ))
7059}
7160
72- // Smithy benchmark model files (tagged @httpRequestTests / @httpResponseTests
73- // with the `serde-benchmark` tag).
74- //
75- // At runtime BenchmarkContext loads the model via
76- // `Model.assembler().discoverModels()`, which walks `META-INF/smithy/manifest`
77- // resources on the classpath.
7861abstract class GenerateSmithyManifest : DefaultTask () {
7962 @get:InputDirectory
8063 abstract val sourceDir: DirectoryProperty
8164
8265 @get:OutputDirectory
8366 abstract val outputDir: DirectoryProperty
8467
85- @org.gradle.api.tasks. TaskAction
68+ @TaskAction
8669 fun run () {
8770 val outRoot = outputDir.get().asFile
8871 val smithyDir = outRoot.resolve(" META-INF/smithy" )
@@ -109,50 +92,14 @@ val generateSmithyManifest by tasks.registering(GenerateSmithyManifest::class) {
10992 outputDir.set(layout.buildDirectory.dir(" generated-resources/smithy-manifest" ))
11093}
11194
112- // Wire each codegen projection's output into the jmh source set. There are
113- // five projections (one per service); each emits Java source under
114- // `build/smithyprojections/<project>/<projection>/java-codegen/java` into a
115- // distinct package so same-named typed shapes from different protocols don't
116- // collide.
117- val codegenProjections =
118- listOf (
119- " aws-json-rpc-1-0-client" ,
120- " aws-query-client" ,
121- " rest-json-client" ,
122- " rest-xml-client" ,
123- " rpc-v2-cbor-client" ,
124- )
125-
126- afterEvaluate {
127- val projectionPaths =
128- codegenProjections.map { name ->
129- smithy.getPluginProjectionPath(name, " java-codegen" ).get()
130- }
131- sourceSets.named(" jmh" ) {
132- java {
133- projectionPaths.forEach { srcDir(" $it /java" ) }
134- }
135- resources {
136- projectionPaths.forEach { srcDir(" $it /resources" ) }
137- srcDir(generateSmithyManifest)
138- }
95+ sourceSets.named(" jmh" ) {
96+ resources {
97+ srcDir(generateSmithyManifest)
13998 }
14099}
141100
142101tasks.named(" processJmhResources" ) {
143102 dependsOn(generateSmithyManifest)
144- dependsOn(" smithyBuild" )
145- }
146-
147- // Multiple codegen projections each register META-INF/services/...SchemaIndex
148- // (and other SPI files). Both should be on the runtime classpath; tell
149- // processJmhResources to keep both entries by concatenating.
150- tasks.named<Copy >(" processJmhResources" ) {
151- duplicatesStrategy = DuplicatesStrategy .INCLUDE
152- }
153-
154- tasks.named(" compileJmhJava" ) {
155- dependsOn(" smithyBuild" )
156103}
157104
158105// Test case: -Pjmh.testCaseId=rpcv2Cbor_PutItemRequest_BinaryData_S
@@ -181,23 +128,11 @@ jmh {
181128 resultsFile = layout.buildDirectory.file(" results/jmh/results.json" )
182129}
183130
184- // With shadow applied before jmh, jmhJar is a ShadowJar. Configure
185- // mergeServiceFiles() so duplicate META-INF/services/ entries from
186- // multiple codegen projections are concatenated rather than overwritten.
187131tasks.jmhJar {
188132 mergeServiceFiles()
189133 append(" META-INF/smithy/manifest" )
190134}
191135
192- // Run the cross-language result converter. Reads the JMH JSON written by the
193- // `jmh` task and writes a JSON + Markdown pair conforming to the shared
194- // benchmark output schema. OS, instance type (via EC2 IMDS), and smithy-java
195- // version are detected at runtime.
196- //
197- // ./gradlew :benchmarks:serde-benchmarks:convertJmhResults
198- //
199- // Optional properties:
200- // -PoutputPrefix=<path> prefix for the output files (default: build/results/jmh/output)
201136tasks.register<JavaExec >(" convertJmhResults" ) {
202137 group = " benchmarks"
203138 description = " Convert JMH JSON output to the cross-language serde benchmark schema."
0 commit comments