Skip to content

Commit f79f548

Browse files
authored
Add Standard (cross-sdk) Benchmarks (#6860)
* Add Endpoint Resolver benchmarks * Added SERDE benchmarks * Add md conversion as well * Update based on PR comments * Improve conversion + add tests * Fix new module verification errors * Fix new module verification script to use correct skip * Fix checkstyle * Update version
1 parent 5ee5d1d commit f79f548

File tree

53 files changed

+52980
-4
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

53 files changed

+52980
-4
lines changed

.brazil.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@
103103
"s3-benchmarks": { "skipImport": true },
104104
"http-client-benchmarks": { "skipImport": true },
105105
"sdk-benchmarks": { "skipImport": true },
106+
"sdk-standard-benchmarks": { "skipImport": true },
106107
"sdk-native-image-test": { "skipImport": true },
107108
"service-test-utils": { "skipImport": true },
108109
"services": { "skipImport": true },

.github/workflows/new-module-verification.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ jobs:
8383
echo "New module detected: $MODULE_DIR"
8484
8585
# Check if it's a test module
86-
if [[ "$MODULE_DIR" == *"/test/"* || "$MODULE_DIR" == *"/it/"* || "$MODULE_DIR" == *"-test"* || "$MODULE_DIR" == *"-tests"* ]]; then
86+
if [[ "$MODULE_DIR" == *"/test/"* || "$MODULE_DIR" == *"/it/"* || "$MODULE_DIR" == *"-test"* || "$MODULE_DIR" == *"-tests"* || "$MODULE_DIR" == *"-benchmarks"* ]]; then
8787
echo "::group::Test module: $MODULE_DIR"
8888
TEST_MODULES=$((TEST_MODULES + 1))
8989
@@ -106,7 +106,7 @@ jobs:
106106
fi
107107
108108
# 3. Check if Brazil import is skipped
109-
if ! grep -q "\"$MODULE_NAME\".*\"skip\".*true" .brazil.json 2>/dev/null; then
109+
if ! grep -q "\"$MODULE_NAME\".*\"skipImport\".*true" .brazil.json 2>/dev/null; then
110110
echo "::error::Module $MODULE_NAME is not configured to skip Brazil import in .brazil.json"
111111
HAS_ERRORS=1
112112
else

buildspecs/release-javadoc.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ phases:
1313
pre_build:
1414
commands:
1515
- DOC_PATH='s3://aws-java-sdk-javadoc/java/api'
16-
- MODULES_TO_SKIP="protocol-tests,protocol-tests-core,codegen-generated-classes-test,sdk-benchmarks,s3-benchmarks,http-client-benchmarks,module-path-tests,test-utils,http-client-tests,tests-coverage-reporting,sdk-native-image-test,ruleset-testing-core,old-client-version-compatibility-test,crt-unavailable-tests,bundle-shading-tests,v2-migration,v2-migration-tests,architecture-tests,s3-tests"
16+
- MODULES_TO_SKIP="protocol-tests,protocol-tests-core,codegen-generated-classes-test,sdk-benchmarks,sdk-standard-benchmarks,s3-benchmarks,http-client-benchmarks,module-path-tests,test-utils,http-client-tests,tests-coverage-reporting,sdk-native-image-test,ruleset-testing-core,old-client-version-compatibility-test,crt-unavailable-tests,bundle-shading-tests,v2-migration,v2-migration-tests,architecture-tests,s3-tests"
1717

1818
build:
1919
commands:

buildspecs/release-to-maven.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ phases:
1616
- SDK_SIGNING_GPG_PASSPHRASE_ARN="arn:aws:secretsmanager:us-east-1:103431983078:secret:sdk-signing-gpg-passphrase-A0H1Kq"
1717
- SONATYPE_PASSWORD_ARN="arn:aws:secretsmanager:us-east-1:103431983078:secret:sonatype-password-I2V6Y0"
1818
- SONATYPE_USERNAME_ARN="arn:aws:secretsmanager:us-east-1:103431983078:secret:sonatype-username-HphNZQ"
19-
- MODULES_TO_SKIP="protocol-tests,protocol-tests-core,codegen-generated-classes-test,sdk-benchmarks,module-path-tests,tests-coverage-reporting,stability-tests,sdk-native-image-test,auth-tests,s3-benchmarks,http-client-benchmarks,region-testing,old-client-version-compatibility-test,crt-unavailable-tests,bundle-shading-tests,v2-migration-tests,architecture-tests,s3-tests"
19+
- MODULES_TO_SKIP="protocol-tests,protocol-tests-core,codegen-generated-classes-test,sdk-benchmarks,sdk-standard-benchmarks,module-path-tests,tests-coverage-reporting,stability-tests,sdk-native-image-test,auth-tests,s3-benchmarks,http-client-benchmarks,region-testing,old-client-version-compatibility-test,crt-unavailable-tests,bundle-shading-tests,v2-migration-tests,architecture-tests,s3-tests"
2020

2121
build:
2222
commands:

pom.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@
8080
<module>test/test-utils</module>
8181
<module>test/codegen-generated-classes-test</module>
8282
<module>test/sdk-benchmarks</module>
83+
<module>test/sdk-standard-benchmarks</module>
8384
<module>test/http-client-benchmarks</module>
8485
<module>test/module-path-tests</module>
8586
<module>test/tests-coverage-reporting</module>
Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
# SDK Standard Benchmarks
2+
3+
This module contains JMH microbenchmarks for the AWS SDK for Java v2, covering
4+
endpoint resolution and serialization/deserialization (serde) across all major
5+
AWS protocol types.
6+
7+
## Building
8+
9+
```bash
10+
mvn clean install -P quick -pl :sdk-standard-benchmarks --am
11+
```
12+
13+
The `--am` flag builds all upstream dependencies (codegen plugin, protocol modules,
14+
etc.). You only need it on the first build or after upstream changes. Subsequent
15+
builds can omit it:
16+
17+
```bash
18+
mvn install -P quick -pl :sdk-standard-benchmarks
19+
```
20+
21+
## Endpoint Resolution Benchmarks
22+
23+
Benchmarks for the standard endpoint resolution pipeline (`ruleParams()`
24+
`resolveEndpoint()`) for S3 and Lambda. These exercise the same code path that
25+
runs during a real SDK API call.
26+
27+
| Class | Service | Test Cases |
28+
|---|---|---|
29+
| `S3EndpointResolverBenchmark` | S3 | 5 (virtual host, path style, S3 Express, access point ARN, outposts ARN) |
30+
| `LambdaEndpointResolverBenchmark` | Lambda | 2 (standard region, GovCloud with FIPS + DualStack) |
31+
32+
```bash
33+
java -jar target/benchmarks.jar S3EndpointResolverBenchmark
34+
java -jar target/benchmarks.jar LambdaEndpointResolverBenchmark
35+
```
36+
37+
## Serde Benchmarks
38+
39+
Benchmarks for serialization (marshaling) and deserialization (unmarshalling)
40+
across five AWS protocol types. Each protocol has a pair of benchmark classes
41+
parameterized by test case ID via JMH `@Param`.
42+
43+
| Protocol | Marshall Class | Unmarshall Class | Input Cases | Output Cases |
44+
|---|---|---|---|---|
45+
| JSON RPC 1.0 | `JsonRpc10MarshallBenchmark` | `JsonRpc10UnmarshallBenchmark` | 33 | 18 |
46+
| AWS Query | `QueryMarshallBenchmark` | `QueryUnmarshallBenchmark` | 33 | 18 |
47+
| REST JSON | `RestJsonMarshallBenchmark` | `RestJsonUnmarshallBenchmark` | 18 | 14 |
48+
| REST XML | `RestXmlMarshallBenchmark` | `RestXmlUnmarshallBenchmark` | 18 | 14 |
49+
| RPC v2 CBOR | `RpcV2CborMarshallBenchmark` | `RpcV2CborUnmarshallBenchmark` | 33 | 18 |
50+
51+
Serde benchmarks use `@BenchmarkMode(Mode.SampleTime)` instead of `AverageTime`.
52+
SampleTime collects per-invocation latency samples, which gives us percentile
53+
data (p50, p90, p95, p99) needed by the cross-language output schema.
54+
55+
### Running serde benchmarks
56+
57+
```bash
58+
# All serde benchmarks (all protocols, all test cases)
59+
java -jar target/benchmarks.jar ".*serde.*"
60+
61+
# Single protocol — marshall only
62+
java -jar target/benchmarks.jar JsonRpc10MarshallBenchmark
63+
64+
# Single protocol — unmarshall only
65+
java -jar target/benchmarks.jar QueryUnmarshallBenchmark
66+
67+
# Quick smoke test: 1 fork, short warmup/measurement
68+
java -jar target/benchmarks.jar JsonRpc10MarshallBenchmark -f 1 -wi 1 -w 1s -i 1 -r 3s -foe true
69+
```
70+
71+
### Producing the cross-language output JSON
72+
73+
The benchmarks produce standard JMH output. To convert it to the cross-language
74+
`output_schema.json` format used for comparison with other SDK implementations
75+
(Ruby, TypeScript, etc.):
76+
77+
```bash
78+
# 1. Run benchmarks and write JMH results as JSON
79+
java -jar target/benchmarks.jar ".*serde.*" -rf json -rff results.json
80+
81+
# 2. Convert to cross-language format (produces output.json and output.md)
82+
java -cp target/benchmarks.jar \
83+
software.amazon.awssdk.benchmark.serde.JmhResultConverter \
84+
results.json output
85+
```
86+
87+
This produces two files:
88+
- `output.json` — the cross-language JSON schema format
89+
- `output.md` — a rendered Markdown table for easy viewing
90+
91+
The output JSON has this structure:
92+
93+
```json
94+
{
95+
"metadata": {
96+
"lang": "Java",
97+
"software": [["smithy-java", "TODO"], ["AWS SDK for Java", "TODO"]],
98+
"os": "TODO",
99+
"instance": "TODO",
100+
"precision": "-9"
101+
},
102+
"serde_benchmarks": [
103+
{
104+
"id": "awsJson1_0_GetItemInput_Baseline",
105+
"n": 5,
106+
"mean": 1234,
107+
"p50": 1200,
108+
"p90": 1500,
109+
"p95": 1600,
110+
"p99": 1800,
111+
"std_dev": 150
112+
}
113+
]
114+
}
115+
```
116+
117+
The `metadata` fields marked `TODO` should be filled in for the target environment
118+
before publishing results.
119+
120+
## General JMH options
121+
122+
```bash
123+
# List all available benchmarks
124+
java -jar target/benchmarks.jar -l
125+
126+
# Custom warmup/measurement: 3 warmup iterations, 5 measurement iterations, 2 forks
127+
java -jar target/benchmarks.jar -wi 3 -i 5 -f 2
128+
129+
# Custom warmup/measurement times:
130+
java -jar target/benchmarks.jar -f 1 -w 1s -r 3s
131+
132+
# Fail on error (useful for CI)
133+
java -jar target/benchmarks.jar -foe true
134+
```
135+
136+
Each benchmark class has default JMH annotations (`@Warmup`, `@Measurement`, `@Fork`)
137+
tailored for stable results. Override them on the command line as needed for your
138+
environment.

0 commit comments

Comments
 (0)