From 36ca8df24b2a6005231f3ebc2cb09943b3089ad2 Mon Sep 17 00:00:00 2001
From: RanVaknin <50976344+RanVaknin@users.noreply.github.com>
Date: Tue, 10 Mar 2026 14:27:35 -0700
Subject: [PATCH 1/7] Add isolated protocol ser/de benchmarks for V1 vs V2
Benchmarks for all 6 AWS protocol types measuring serialization and
deserialization in isolation (no HTTP, signing, or retries):
- JSON (DynamoDB PutItem)
- REST-JSON (Lambda CreateFunction)
- REST-XML (CloudFront CreateDistribution)
- Query (STS AssumeRole)
- EC2 (EC2 DescribeInstances)
- CBOR (CloudWatch GetMetricData)
Each protocol has a V1 and V2 benchmark class with @Benchmark methods
for both ser and deser, using the same JMH configuration and fixture
data for fair comparison.
---
.../amazon/awssdk/checkstyle-suppressions.xml | 4 +
test/sdk-benchmarks/pom.xml | 42 +++-
.../protocol/V1CborProtocolBenchmark.java | 140 ++++++++++++
.../protocol/V1Ec2ProtocolBenchmark.java | 98 ++++++++
.../protocol/V1JsonProtocolBenchmark.java | 125 +++++++++++
.../protocol/V1QueryProtocolBenchmark.java | 97 ++++++++
.../protocol/V1RestJsonProtocolBenchmark.java | 124 +++++++++++
.../protocol/V1RestXmlProtocolBenchmark.java | 138 ++++++++++++
.../protocol/V2CborProtocolBenchmark.java | 178 +++++++++++++++
.../protocol/V2Ec2ProtocolBenchmark.java | 117 ++++++++++
.../protocol/V2JsonProtocolBenchmark.java | 151 +++++++++++++
.../protocol/V2QueryProtocolBenchmark.java | 117 ++++++++++
.../protocol/V2RestJsonProtocolBenchmark.java | 153 +++++++++++++
.../protocol/V2RestXmlProtocolBenchmark.java | 154 +++++++++++++
.../describe-instances-response.xml | 37 ++++
.../json-protocol/putitem-response.json | 24 ++
.../query-protocol/assumerole-response.xml | 19 ++
.../createfunction-response.json | 43 ++++
.../create-distribution-response.xml | 209 ++++++++++++++++++
19 files changed, 1969 insertions(+), 1 deletion(-)
create mode 100644 test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/protocol/V1CborProtocolBenchmark.java
create mode 100644 test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/protocol/V1Ec2ProtocolBenchmark.java
create mode 100644 test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/protocol/V1JsonProtocolBenchmark.java
create mode 100644 test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/protocol/V1QueryProtocolBenchmark.java
create mode 100644 test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/protocol/V1RestJsonProtocolBenchmark.java
create mode 100644 test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/protocol/V1RestXmlProtocolBenchmark.java
create mode 100644 test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/protocol/V2CborProtocolBenchmark.java
create mode 100644 test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/protocol/V2Ec2ProtocolBenchmark.java
create mode 100644 test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/protocol/V2JsonProtocolBenchmark.java
create mode 100644 test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/protocol/V2QueryProtocolBenchmark.java
create mode 100644 test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/protocol/V2RestJsonProtocolBenchmark.java
create mode 100644 test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/protocol/V2RestXmlProtocolBenchmark.java
create mode 100644 test/sdk-benchmarks/src/main/resources/fixtures/ec2-protocol/describe-instances-response.xml
create mode 100644 test/sdk-benchmarks/src/main/resources/fixtures/json-protocol/putitem-response.json
create mode 100644 test/sdk-benchmarks/src/main/resources/fixtures/query-protocol/assumerole-response.xml
create mode 100644 test/sdk-benchmarks/src/main/resources/fixtures/rest-json-protocol/createfunction-response.json
create mode 100644 test/sdk-benchmarks/src/main/resources/fixtures/rest-xml-protocol/create-distribution-response.xml
diff --git a/build-tools/src/main/resources/software/amazon/awssdk/checkstyle-suppressions.xml b/build-tools/src/main/resources/software/amazon/awssdk/checkstyle-suppressions.xml
index 17c617c0d12b..ab1f3ade8258 100644
--- a/build-tools/src/main/resources/software/amazon/awssdk/checkstyle-suppressions.xml
+++ b/build-tools/src/main/resources/software/amazon/awssdk/checkstyle-suppressions.xml
@@ -50,6 +50,10 @@
+
+
+
diff --git a/test/sdk-benchmarks/pom.xml b/test/sdk-benchmarks/pom.xml
index 4f0a47cfc17a..983d5badbfd9 100644
--- a/test/sdk-benchmarks/pom.xml
+++ b/test/sdk-benchmarks/pom.xml
@@ -47,7 +47,7 @@
-->
benchmarks
- 1.11.404
+ 1.12.797
1.6.0
@@ -87,18 +87,58 @@
aws-java-sdk-ec2
${sdk-v1.version}
+
+ com.amazonaws
+ aws-java-sdk-cloudfront
+ ${sdk-v1.version}
+
+
+ com.amazonaws
+ aws-java-sdk-sts
+ ${sdk-v1.version}
+
+
+ com.amazonaws
+ aws-java-sdk-lambda
+ ${sdk-v1.version}
+
+
+ com.amazonaws
+ aws-java-sdk-cloudwatch
+ ${sdk-v1.version}
+
software.amazon.awssdk
ec2
${awsjavasdk.version}
+
+ software.amazon.awssdk
+ cloudfront
+ ${awsjavasdk.version}
+
+
+ software.amazon.awssdk
+ sts
+ ${awsjavasdk.version}
+
+
+ software.amazon.awssdk
+ lambda
+ ${awsjavasdk.version}
+
software.amazon.awssdk
aws-query-protocol
${awsjavasdk.version}
+
+ software.amazon.awssdk
+ smithy-rpcv2-protocol
+ ${awsjavasdk.version}
+
software.amazon.awssdk
diff --git a/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/protocol/V1CborProtocolBenchmark.java b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/protocol/V1CborProtocolBenchmark.java
new file mode 100644
index 000000000000..5b0e1e59a3dc
--- /dev/null
+++ b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/protocol/V1CborProtocolBenchmark.java
@@ -0,0 +1,140 @@
+/*
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License").
+ * You may not use this file except in compliance with the License.
+ * A copy of the License is located at
+ *
+ * http://aws.amazon.com/apache2.0
+ *
+ * or in the "license" file accompanying this file. This file is distributed
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+package software.amazon.awssdk.benchmark.protocol;
+
+import com.amazonaws.protocol.rpcv2cbor.RpcV2CborClientMetadata;
+import com.amazonaws.protocol.rpcv2cbor.SdkRpcV2CborProtocolFactory;
+import com.amazonaws.protocol.rpcv2cbor.SdkStructuredCborFactory;
+import com.amazonaws.protocol.rpcv2cbor.StructuredRpcV2CborGenerator;
+import com.amazonaws.services.cloudwatch.model.GetMetricDataRequest;
+import com.amazonaws.services.cloudwatch.model.Metric;
+import com.amazonaws.services.cloudwatch.model.MetricDataQuery;
+import com.amazonaws.services.cloudwatch.model.MetricStat;
+import com.amazonaws.services.cloudwatch.model.transform.GetMetricDataRequestProtocolMarshaller;
+import com.amazonaws.services.cloudwatch.model.transform.GetMetricDataResultRpcV2CborUnmarshaller;
+import com.amazonaws.transform.rpcv2cbor.RpcV2CborUnmarshallerContextImpl;
+import com.fasterxml.jackson.dataformat.cbor.CBORFactory;
+import com.fasterxml.jackson.dataformat.cbor.CBORParser;
+import java.util.Date;
+import java.util.concurrent.TimeUnit;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Fork;
+import org.openjdk.jmh.annotations.Measurement;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.annotations.Warmup;
+import org.openjdk.jmh.infra.Blackhole;
+
+/**
+ * Isolated ser/de benchmark for V1 CloudWatch (smithy-rpc-v2-cbor protocol).
+ * Measures only CBOR parsing + object construction -- no HTTP, signing, or retries.
+ */
+@State(Scope.Benchmark)
+@BenchmarkMode(Mode.SampleTime)
+@OutputTimeUnit(TimeUnit.MICROSECONDS)
+@Warmup(iterations = 5)
+@Measurement(iterations = 5)
+@Fork(2)
+public class V1CborProtocolBenchmark {
+
+ private static final CBORFactory CBOR_FACTORY = new CBORFactory();
+
+ private SdkRpcV2CborProtocolFactory protocolFactory;
+ private byte[] responseBytes;
+ private GetMetricDataRequest request;
+
+ @Setup
+ public void setup() throws Exception {
+ protocolFactory = new SdkRpcV2CborProtocolFactory(new RpcV2CborClientMetadata());
+ responseBytes = createCborResponseFixture();
+ request = createRequest();
+ }
+
+ @Benchmark
+ public void getMetricDataDeser(Blackhole bh) throws Exception {
+ CBORParser parser = CBOR_FACTORY.createParser(responseBytes);
+ RpcV2CborUnmarshallerContextImpl ctx = new RpcV2CborUnmarshallerContextImpl(
+ parser, SdkStructuredCborFactory.CBOR_SCALAR_UNMARSHALLERS, null);
+ ctx.nextToken();
+ bh.consume(GetMetricDataResultRpcV2CborUnmarshaller.getInstance().unmarshall(ctx));
+ }
+
+ @Benchmark
+ public void getMetricDataSer(Blackhole bh) {
+ bh.consume(new GetMetricDataRequestProtocolMarshaller(protocolFactory).marshall(request));
+ }
+
+ private static GetMetricDataRequest createRequest() {
+ Date end = Date.from(java.time.Instant.parse("2026-03-09T00:00:00Z"));
+ Date start = Date.from(java.time.Instant.parse("2026-03-09T00:00:00Z").minusSeconds(3600));
+ return new GetMetricDataRequest()
+ .withStartTime(start)
+ .withEndTime(end)
+ .withMaxDatapoints(1000)
+ .withMetricDataQueries(
+ new MetricDataQuery()
+ .withId("cpu")
+ .withMetricStat(new MetricStat()
+ .withMetric(new Metric()
+ .withNamespace("AWS/EC2")
+ .withMetricName("CPUUtilization"))
+ .withPeriod(300)
+ .withStat("Average"))
+ .withReturnData(true));
+ }
+
+ private static byte[] createCborResponseFixture() {
+ StructuredRpcV2CborGenerator gen =
+ SdkStructuredCborFactory.SDK_CBOR_FACTORY.createWriter("application/cbor");
+ gen.writeStartObject();
+ gen.writeFieldName("MetricDataResults");
+ gen.writeStartArray();
+ gen.writeStartObject();
+ gen.writeFieldName("Id");
+ gen.writeValue("cpu");
+ gen.writeFieldName("Label");
+ gen.writeValue("CPUUtilization");
+ gen.writeFieldName("StatusCode");
+ gen.writeValue("Complete");
+ gen.writeFieldName("Timestamps");
+ gen.writeStartArray();
+ long base = 1772611200L;
+ for (int i = 0; i < 12; i++) {
+ gen.writeValue((double) ((base + i * 300) * 1000));
+ }
+ gen.writeEndArray();
+ gen.writeFieldName("Values");
+ gen.writeStartArray();
+ for (int i = 0; i < 12; i++) {
+ gen.writeValue(45.2 + i * 1.1);
+ }
+ gen.writeEndArray();
+ gen.writeFieldName("Messages");
+ gen.writeStartArray();
+ gen.writeEndArray();
+ gen.writeEndObject();
+ gen.writeEndArray();
+ gen.writeFieldName("Messages");
+ gen.writeStartArray();
+ gen.writeEndArray();
+ gen.writeEndObject();
+ return gen.getBytes();
+ }
+}
diff --git a/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/protocol/V1Ec2ProtocolBenchmark.java b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/protocol/V1Ec2ProtocolBenchmark.java
new file mode 100644
index 000000000000..82d8e01d7bd7
--- /dev/null
+++ b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/protocol/V1Ec2ProtocolBenchmark.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License").
+ * You may not use this file except in compliance with the License.
+ * A copy of the License is located at
+ *
+ * http://aws.amazon.com/apache2.0
+ *
+ * or in the "license" file accompanying this file. This file is distributed
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+package software.amazon.awssdk.benchmark.protocol;
+
+import com.amazonaws.services.ec2.model.DescribeInstancesRequest;
+import com.amazonaws.services.ec2.model.Filter;
+import com.amazonaws.services.ec2.model.transform.DescribeInstancesRequestMarshaller;
+import com.amazonaws.services.ec2.model.transform.DescribeInstancesResultStaxUnmarshaller;
+import com.amazonaws.transform.StaxUnmarshallerContext;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+import javax.xml.stream.XMLEventReader;
+import javax.xml.stream.XMLInputFactory;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Fork;
+import org.openjdk.jmh.annotations.Measurement;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.annotations.Warmup;
+import org.openjdk.jmh.infra.Blackhole;
+
+/**
+ * Isolated ser/de benchmark for V1 EC2 (EC2 Query protocol).
+ * Measures only XML parsing + form encoding -- no HTTP, signing, or retries.
+ */
+@State(Scope.Benchmark)
+@BenchmarkMode(Mode.SampleTime)
+@OutputTimeUnit(TimeUnit.MICROSECONDS)
+@Warmup(iterations = 5)
+@Measurement(iterations = 5)
+@Fork(2)
+public class V1Ec2ProtocolBenchmark {
+
+ private static final XMLInputFactory XML_INPUT_FACTORY =
+ XMLInputFactory.newInstance();
+
+ private byte[] responseBytes;
+ private Map responseHeaders;
+ private DescribeInstancesRequestMarshaller marshaller;
+ private DescribeInstancesRequest request;
+
+ @Setup
+ public void setup() throws Exception {
+ responseBytes = loadFixture("fixtures/ec2-protocol/describe-instances-response.xml");
+ responseHeaders = new HashMap<>();
+ marshaller = new DescribeInstancesRequestMarshaller();
+ request = createRequest();
+ }
+
+ @Benchmark
+ public void describeInstancesDeser(Blackhole bh) throws Exception {
+ XMLEventReader reader = XML_INPUT_FACTORY.createXMLEventReader(new ByteArrayInputStream(responseBytes));
+ StaxUnmarshallerContext ctx = new StaxUnmarshallerContext(reader, responseHeaders);
+ ctx.registerMetadataExpression("ResponseMetadata/RequestId", 2, "AWS_REQUEST_ID");
+
+ bh.consume(DescribeInstancesResultStaxUnmarshaller.getInstance().unmarshall(ctx));
+ }
+
+ @Benchmark
+ public void describeInstancesSer(Blackhole bh) {
+ bh.consume(marshaller.marshall(request));
+ }
+
+ private static DescribeInstancesRequest createRequest() {
+ return new DescribeInstancesRequest()
+ .withInstanceIds("i-0abcdef1234567890")
+ .withFilters(
+ new Filter("instance-state-name").withValues("running"),
+ new Filter("instance-type").withValues("m5.xlarge"))
+ .withMaxResults(100);
+ }
+
+ private static byte[] loadFixture(String path) throws IOException {
+ return com.amazonaws.util.IOUtils.toByteArray(
+ V1Ec2ProtocolBenchmark.class.getClassLoader()
+ .getResourceAsStream(path));
+ }
+}
diff --git a/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/protocol/V1JsonProtocolBenchmark.java b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/protocol/V1JsonProtocolBenchmark.java
new file mode 100644
index 000000000000..5cf300685a02
--- /dev/null
+++ b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/protocol/V1JsonProtocolBenchmark.java
@@ -0,0 +1,125 @@
+/*
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License").
+ * You may not use this file except in compliance with the License.
+ * A copy of the License is located at
+ *
+ * http://aws.amazon.com/apache2.0
+ *
+ * or in the "license" file accompanying this file. This file is distributed
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+package software.amazon.awssdk.benchmark.protocol;
+
+import com.amazonaws.http.HttpResponse;
+import com.amazonaws.protocol.json.JsonClientMetadata;
+import com.amazonaws.protocol.json.SdkJsonProtocolFactory;
+import com.amazonaws.protocol.json.SdkStructuredPlainJsonFactory;
+import com.amazonaws.services.dynamodbv2.model.AttributeValue;
+import com.amazonaws.services.dynamodbv2.model.PutItemRequest;
+import com.amazonaws.services.dynamodbv2.model.transform.PutItemRequestProtocolMarshaller;
+import com.amazonaws.services.dynamodbv2.model.transform.PutItemResultJsonUnmarshaller;
+import com.amazonaws.transform.JsonUnmarshallerContextImpl;
+import com.fasterxml.jackson.core.JsonFactory;
+import com.fasterxml.jackson.core.JsonParser;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Fork;
+import org.openjdk.jmh.annotations.Measurement;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.annotations.Warmup;
+import org.openjdk.jmh.infra.Blackhole;
+
+/**
+ * Isolated ser/de benchmark for V1 DynamoDB (JSON protocol).
+ * Measures only JSON parsing + object construction -- no HTTP, signing, or retries.
+ */
+@State(Scope.Benchmark)
+@BenchmarkMode(Mode.SampleTime)
+@OutputTimeUnit(TimeUnit.MICROSECONDS)
+@Warmup(iterations = 5)
+@Measurement(iterations = 5)
+@Fork(2)
+public class V1JsonProtocolBenchmark {
+
+ private static final JsonFactory JSON_FACTORY = new JsonFactory();
+ private byte[] putItemResponseBytes;
+ private HttpResponse httpResponse;
+ private SdkJsonProtocolFactory protocolFactory;
+ private PutItemRequest putItemRequest;
+
+ @Setup
+ public void setup() throws Exception {
+ putItemResponseBytes = loadFixture("fixtures/json-protocol/putitem-response.json");
+ httpResponse = new HttpResponse(null, null);
+ httpResponse.setStatusCode(200);
+ protocolFactory = new SdkJsonProtocolFactory(
+ new JsonClientMetadata().withProtocolVersion("1.0"));
+ putItemRequest = new PutItemRequest()
+ .withTableName("benchmark-table")
+ .withItem(itemMap());
+ }
+
+ @Benchmark
+ public void putItemDeser(Blackhole bh) throws Exception {
+ JsonParser parser = JSON_FACTORY.createParser(new ByteArrayInputStream(putItemResponseBytes));
+ JsonUnmarshallerContextImpl ctx = new JsonUnmarshallerContextImpl(parser,
+ SdkStructuredPlainJsonFactory.JSON_SCALAR_UNMARSHALLERS,
+ SdkStructuredPlainJsonFactory.JSON_CUSTOM_TYPE_UNMARSHALLERS,
+ httpResponse);
+
+ bh.consume(PutItemResultJsonUnmarshaller.getInstance().unmarshall(ctx));
+ }
+
+ @Benchmark
+ public void putItemSer(Blackhole bh) {
+ bh.consume(new PutItemRequestProtocolMarshaller(protocolFactory).marshall(putItemRequest));
+ }
+
+ private static Map itemMap() {
+ Map item = new HashMap();
+ item.put("pk", new AttributeValue().withS("benchmark-key"));
+ item.put("sk", new AttributeValue().withN("100"));
+ item.put("stringField", new AttributeValue().withS("test-value"));
+ item.put("numberField", new AttributeValue().withN("123.456"));
+ item.put("binaryField", new AttributeValue()
+ .withB(ByteBuffer.wrap("hello world".getBytes())));
+ item.put("stringSetField", new AttributeValue()
+ .withSS("value1", "value2", "value3"));
+ item.put("numberSetField", new AttributeValue()
+ .withNS("1.1", "2.2", "3.3"));
+ item.put("boolField", new AttributeValue().withBOOL(false));
+ item.put("nullField", new AttributeValue().withNULL(true));
+ Map deep = new HashMap();
+ deep.put("level2", new AttributeValue().withN("999"));
+ Map nested = new HashMap();
+ nested.put("nested", new AttributeValue().withS("nested-value"));
+ nested.put("deepNested", new AttributeValue().withM(deep));
+ item.put("mapField", new AttributeValue().withM(nested));
+ item.put("listField", new AttributeValue().withL(
+ new AttributeValue().withS("item1"),
+ new AttributeValue().withN("42"),
+ new AttributeValue().withBOOL(true),
+ new AttributeValue().withNULL(true)));
+ return item;
+ }
+
+ private static byte[] loadFixture(String path) throws IOException {
+ return com.amazonaws.util.IOUtils.toByteArray(
+ V1JsonProtocolBenchmark.class.getClassLoader().getResourceAsStream(path));
+ }
+}
diff --git a/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/protocol/V1QueryProtocolBenchmark.java b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/protocol/V1QueryProtocolBenchmark.java
new file mode 100644
index 000000000000..1f004d209b85
--- /dev/null
+++ b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/protocol/V1QueryProtocolBenchmark.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License").
+ * You may not use this file except in compliance with the License.
+ * A copy of the License is located at
+ *
+ * http://aws.amazon.com/apache2.0
+ *
+ * or in the "license" file accompanying this file. This file is distributed
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+package software.amazon.awssdk.benchmark.protocol;
+
+import com.amazonaws.services.securitytoken.model.AssumeRoleRequest;
+import com.amazonaws.services.securitytoken.model.transform.AssumeRoleRequestMarshaller;
+import com.amazonaws.services.securitytoken.model.transform.AssumeRoleResultStaxUnmarshaller;
+import com.amazonaws.transform.StaxUnmarshallerContext;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+import javax.xml.stream.XMLEventReader;
+import javax.xml.stream.XMLInputFactory;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Fork;
+import org.openjdk.jmh.annotations.Measurement;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.annotations.Warmup;
+import org.openjdk.jmh.infra.Blackhole;
+
+/**
+ * Isolated ser/de benchmark for V1 STS (Query protocol).
+ * Measures only XML parsing + form encoding -- no HTTP, signing, or retries.
+ */
+@State(Scope.Benchmark)
+@BenchmarkMode(Mode.SampleTime)
+@OutputTimeUnit(TimeUnit.MICROSECONDS)
+@Warmup(iterations = 5)
+@Measurement(iterations = 5)
+@Fork(2)
+public class V1QueryProtocolBenchmark {
+
+ private static final XMLInputFactory XML_INPUT_FACTORY =
+ XMLInputFactory.newInstance();
+
+ private byte[] responseBytes;
+ private Map responseHeaders;
+ private AssumeRoleRequestMarshaller marshaller;
+ private AssumeRoleRequest request;
+
+ @Setup
+ public void setup() throws Exception {
+ responseBytes = loadFixture("fixtures/query-protocol/assumerole-response.xml");
+ responseHeaders = new HashMap<>();
+ marshaller = new AssumeRoleRequestMarshaller();
+ request = createRequest();
+ }
+
+ @Benchmark
+ public void assumeRoleDeser(Blackhole bh) throws Exception {
+ XMLEventReader reader = XML_INPUT_FACTORY.createXMLEventReader(new ByteArrayInputStream(responseBytes));
+ StaxUnmarshallerContext ctx = new StaxUnmarshallerContext(reader, responseHeaders);
+ ctx.registerMetadataExpression("ResponseMetadata/RequestId", 2, "AWS_REQUEST_ID");
+
+ bh.consume(AssumeRoleResultStaxUnmarshaller.getInstance().unmarshall(ctx));
+ }
+
+ @Benchmark
+ public void assumeRoleSer(Blackhole bh) {
+ bh.consume(marshaller.marshall(request));
+ }
+
+ private static AssumeRoleRequest createRequest() {
+ return new AssumeRoleRequest()
+ .withRoleArn("arn:aws:iam::123456789012:role/benchmark-role")
+ .withRoleSessionName("benchmark-session")
+ .withDurationSeconds(3600)
+ .withExternalId("benchmark-external-id")
+ .withPolicy("{\"Version\":\"2012-10-17\"}");
+ }
+
+ private static byte[] loadFixture(String path) throws IOException {
+ return com.amazonaws.util.IOUtils.toByteArray(
+ V1QueryProtocolBenchmark.class.getClassLoader()
+ .getResourceAsStream(path));
+ }
+}
diff --git a/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/protocol/V1RestJsonProtocolBenchmark.java b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/protocol/V1RestJsonProtocolBenchmark.java
new file mode 100644
index 000000000000..c2a48bd076d2
--- /dev/null
+++ b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/protocol/V1RestJsonProtocolBenchmark.java
@@ -0,0 +1,124 @@
+/*
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License").
+ * You may not use this file except in compliance with the License.
+ * A copy of the License is located at
+ *
+ * http://aws.amazon.com/apache2.0
+ *
+ * or in the "license" file accompanying this file. This file is distributed
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+package software.amazon.awssdk.benchmark.protocol;
+
+import com.amazonaws.http.HttpResponse;
+import com.amazonaws.protocol.json.JsonClientMetadata;
+import com.amazonaws.protocol.json.SdkJsonProtocolFactory;
+import com.amazonaws.protocol.json.SdkStructuredPlainJsonFactory;
+import com.amazonaws.services.lambda.model.CreateFunctionRequest;
+import com.amazonaws.services.lambda.model.Environment;
+import com.amazonaws.services.lambda.model.FunctionCode;
+import com.amazonaws.services.lambda.model.Runtime;
+import com.amazonaws.services.lambda.model.TracingConfig;
+import com.amazonaws.services.lambda.model.TracingMode;
+import com.amazonaws.services.lambda.model.transform.CreateFunctionRequestProtocolMarshaller;
+import com.amazonaws.services.lambda.model.transform.CreateFunctionResultJsonUnmarshaller;
+import com.amazonaws.transform.JsonUnmarshallerContextImpl;
+import com.fasterxml.jackson.core.JsonFactory;
+import com.fasterxml.jackson.core.JsonParser;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Fork;
+import org.openjdk.jmh.annotations.Measurement;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.annotations.Warmup;
+import org.openjdk.jmh.infra.Blackhole;
+
+/**
+ * Isolated ser/de benchmark for V1 Lambda (REST-JSON protocol).
+ * Measures only JSON parsing + object construction -- no HTTP, signing, or retries.
+ */
+@State(Scope.Benchmark)
+@BenchmarkMode(Mode.SampleTime)
+@OutputTimeUnit(TimeUnit.MICROSECONDS)
+@Warmup(iterations = 5)
+@Measurement(iterations = 5)
+@Fork(2)
+public class V1RestJsonProtocolBenchmark {
+
+ private static final JsonFactory JSON_FACTORY = new JsonFactory();
+
+ private byte[] responseBytes;
+ private HttpResponse httpResponse;
+ private SdkJsonProtocolFactory protocolFactory;
+ private CreateFunctionRequest request;
+
+ @Setup
+ public void setup() throws Exception {
+ responseBytes = loadFixture("fixtures/rest-json-protocol/createfunction-response.json");
+ httpResponse = new HttpResponse(null, null);
+ httpResponse.setStatusCode(200);
+ protocolFactory = new SdkJsonProtocolFactory(new JsonClientMetadata()
+ .withProtocolVersion("1.1")
+ .withContentTypeOverride("application/json"));
+ request = createRequest();
+ }
+
+ @Benchmark
+ public void createFunctionDeser(Blackhole bh) throws Exception {
+ JsonParser parser = JSON_FACTORY.createParser(new ByteArrayInputStream(responseBytes));
+ JsonUnmarshallerContextImpl ctx = new JsonUnmarshallerContextImpl(
+ parser,
+ SdkStructuredPlainJsonFactory.JSON_SCALAR_UNMARSHALLERS,
+ SdkStructuredPlainJsonFactory.JSON_CUSTOM_TYPE_UNMARSHALLERS,
+ httpResponse);
+
+ bh.consume(CreateFunctionResultJsonUnmarshaller.getInstance().unmarshall(ctx));
+ }
+
+ @Benchmark
+ public void createFunctionSer(Blackhole bh) {
+ bh.consume(new CreateFunctionRequestProtocolMarshaller(protocolFactory)
+ .marshall(request));
+ }
+
+ private static CreateFunctionRequest createRequest() {
+ Map envVars = new HashMap<>();
+ envVars.put("ENV_VAR_1", "value1");
+
+ return new CreateFunctionRequest()
+ .withFunctionName("benchmark-function")
+ .withRuntime(Runtime.Java8)
+ .withRole("arn:aws:iam::123456789012:role/lambda-role")
+ .withHandler("com.example.Handler::handleRequest")
+ .withCode(new FunctionCode()
+ .withS3Bucket("my-deploy-bucket")
+ .withS3Key("code/function.zip"))
+ .withDescription("Benchmark test function")
+ .withTimeout(30)
+ .withMemorySize(512)
+ .withPublish(false)
+ .withEnvironment(new Environment().withVariables(envVars))
+ .withTracingConfig(new TracingConfig()
+ .withMode(TracingMode.Active));
+ }
+
+ private static byte[] loadFixture(String path) throws IOException {
+ return com.amazonaws.util.IOUtils.toByteArray(
+ V1RestJsonProtocolBenchmark.class.getClassLoader()
+ .getResourceAsStream(path));
+ }
+}
diff --git a/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/protocol/V1RestXmlProtocolBenchmark.java b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/protocol/V1RestXmlProtocolBenchmark.java
new file mode 100644
index 000000000000..bca728d7ef52
--- /dev/null
+++ b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/protocol/V1RestXmlProtocolBenchmark.java
@@ -0,0 +1,138 @@
+/*
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License").
+ * You may not use this file except in compliance with the License.
+ * A copy of the License is located at
+ *
+ * http://aws.amazon.com/apache2.0
+ *
+ * or in the "license" file accompanying this file. This file is distributed
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+package software.amazon.awssdk.benchmark.protocol;
+
+import com.amazonaws.http.HttpResponse;
+import com.amazonaws.services.cloudfront.model.Aliases;
+import com.amazonaws.services.cloudfront.model.AllowedMethods;
+import com.amazonaws.services.cloudfront.model.CachedMethods;
+import com.amazonaws.services.cloudfront.model.CreateDistributionRequest;
+import com.amazonaws.services.cloudfront.model.DefaultCacheBehavior;
+import com.amazonaws.services.cloudfront.model.DistributionConfig;
+import com.amazonaws.services.cloudfront.model.Method;
+import com.amazonaws.services.cloudfront.model.Origin;
+import com.amazonaws.services.cloudfront.model.Origins;
+import com.amazonaws.services.cloudfront.model.S3OriginConfig;
+import com.amazonaws.services.cloudfront.model.ViewerProtocolPolicy;
+import com.amazonaws.services.cloudfront.model.transform.CreateDistributionRequestMarshaller;
+import com.amazonaws.services.cloudfront.model.transform.CreateDistributionResultStaxUnmarshaller;
+import com.amazonaws.transform.StaxUnmarshallerContext;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+import javax.xml.stream.XMLEventReader;
+import javax.xml.stream.XMLInputFactory;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Fork;
+import org.openjdk.jmh.annotations.Measurement;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.annotations.Warmup;
+import org.openjdk.jmh.infra.Blackhole;
+
+/**
+ * Isolated ser/de benchmark for V1 CloudFront (REST-XML protocol).
+ * Measures only XML parsing + object construction -- no HTTP, signing, or retries.
+ */
+@State(Scope.Benchmark)
+@BenchmarkMode(Mode.SampleTime)
+@OutputTimeUnit(TimeUnit.MICROSECONDS)
+@Warmup(iterations = 5)
+@Measurement(iterations = 5)
+@Fork(2)
+public class V1RestXmlProtocolBenchmark {
+
+ private static final XMLInputFactory XML_INPUT_FACTORY = XMLInputFactory.newInstance();
+
+ private byte[] responseBytes;
+ private Map responseHeaders;
+ private CreateDistributionRequestMarshaller marshaller;
+ private CreateDistributionRequest request;
+
+ @Setup
+ public void setup() throws Exception {
+ responseBytes = loadFixture("fixtures/rest-xml-protocol/create-distribution-response.xml");
+
+ responseHeaders = new HashMap<>();
+ responseHeaders.put("ETag", "E2QWRUHEXAMPLE");
+ responseHeaders.put("Location", "https://cloudfront.amazonaws.com/2020-05-31/distribution/EDFDVBD6EXAMPLE");
+
+ HttpResponse httpResponse = new HttpResponse(null, null);
+ httpResponse.setStatusCode(200);
+ for (Map.Entry e : responseHeaders.entrySet()) {
+ httpResponse.addHeader(e.getKey(), e.getValue());
+ }
+
+ marshaller = new CreateDistributionRequestMarshaller();
+ request = createRequest();
+ }
+
+ @Benchmark
+ public void createDistributionDeser(Blackhole bh) throws Exception {
+ XMLEventReader reader = XML_INPUT_FACTORY.createXMLEventReader(new ByteArrayInputStream(responseBytes));
+ StaxUnmarshallerContext ctx = new StaxUnmarshallerContext(
+ reader, responseHeaders);
+ ctx.registerMetadataExpression("ResponseMetadata/RequestId", 2, "AWS_REQUEST_ID");
+ bh.consume(CreateDistributionResultStaxUnmarshaller.getInstance().unmarshall(ctx));
+ }
+
+ @Benchmark
+ public void createDistributionSer(Blackhole bh) {
+ bh.consume(marshaller.marshall(request));
+ }
+
+ private static CreateDistributionRequest createRequest() {
+ return new CreateDistributionRequest()
+ .withDistributionConfig(new DistributionConfig()
+ .withCallerReference("benchmark-ref-2024")
+ .withAliases(new Aliases()
+ .withQuantity(2)
+ .withItems("www.example.com", "cdn.example.com"))
+ .withDefaultRootObject("index.html")
+ .withOrigins(new Origins()
+ .withQuantity(1)
+ .withItems(new Origin()
+ .withId("myS3Origin")
+ .withDomainName("mybucket.s3.amazonaws.com")
+ .withOriginPath("/production")
+ .withS3OriginConfig(new S3OriginConfig()
+ .withOriginAccessIdentity(
+ "origin-access-identity/cloudfront/E127EXAMPLE51Z"))))
+ .withDefaultCacheBehavior(new DefaultCacheBehavior()
+ .withTargetOriginId("myS3Origin")
+ .withViewerProtocolPolicy(
+ ViewerProtocolPolicy.RedirectToHttps)
+ .withAllowedMethods(new AllowedMethods()
+ .withQuantity(3)
+ .withItems(Method.GET, Method.HEAD, Method.OPTIONS)
+ .withCachedMethods(new CachedMethods()
+ .withQuantity(2)
+ .withItems(Method.GET, Method.HEAD)))
+ .withCompress(true)));
+ }
+
+ private static byte[] loadFixture(String path) throws IOException {
+ return com.amazonaws.util.IOUtils.toByteArray(
+ V1RestXmlProtocolBenchmark.class.getClassLoader()
+ .getResourceAsStream(path));
+ }
+}
diff --git a/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/protocol/V2CborProtocolBenchmark.java b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/protocol/V2CborProtocolBenchmark.java
new file mode 100644
index 000000000000..fd0ed68839e0
--- /dev/null
+++ b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/protocol/V2CborProtocolBenchmark.java
@@ -0,0 +1,178 @@
+/*
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License").
+ * You may not use this file except in compliance with the License.
+ * A copy of the License is located at
+ *
+ * http://aws.amazon.com/apache2.0
+ *
+ * or in the "license" file accompanying this file. This file is distributed
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+package software.amazon.awssdk.benchmark.protocol;
+
+import java.io.ByteArrayInputStream;
+import java.net.URI;
+import java.time.Instant;
+import java.util.concurrent.TimeUnit;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Fork;
+import org.openjdk.jmh.annotations.Measurement;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.annotations.Warmup;
+import org.openjdk.jmh.infra.Blackhole;
+import software.amazon.awssdk.http.AbortableInputStream;
+import software.amazon.awssdk.http.SdkHttpFullRequest;
+import software.amazon.awssdk.http.SdkHttpFullResponse;
+import software.amazon.awssdk.http.SdkHttpMethod;
+import software.amazon.awssdk.protocols.core.OperationInfo;
+import software.amazon.awssdk.protocols.core.ProtocolMarshaller;
+import software.amazon.awssdk.protocols.json.AwsJsonProtocol;
+import software.amazon.awssdk.protocols.json.AwsJsonProtocolMetadata;
+import software.amazon.awssdk.protocols.json.StructuredJsonGenerator;
+import software.amazon.awssdk.protocols.json.internal.marshall.JsonProtocolMarshallerBuilder;
+import software.amazon.awssdk.protocols.json.internal.unmarshall.JsonProtocolUnmarshaller;
+import software.amazon.awssdk.protocols.rpcv2.SmithyRpcV2CborProtocolFactory;
+import software.amazon.awssdk.protocols.rpcv2.internal.SdkStructuredRpcV2CborFactory;
+import software.amazon.awssdk.services.cloudwatch.model.GetMetricDataRequest;
+import software.amazon.awssdk.services.cloudwatch.model.GetMetricDataResponse;
+import software.amazon.awssdk.services.cloudwatch.model.Metric;
+import software.amazon.awssdk.services.cloudwatch.model.MetricDataQuery;
+import software.amazon.awssdk.services.cloudwatch.model.MetricStat;
+
+/**
+ * Isolated ser/de benchmark for V2 CloudWatch (smithy-rpc-v2-cbor protocol).
+ * Measures only CBOR parsing + object construction -- no HTTP, signing, or retries.
+ */
+@State(Scope.Benchmark)
+@BenchmarkMode(Mode.SampleTime)
+@OutputTimeUnit(TimeUnit.MICROSECONDS)
+@Warmup(iterations = 5)
+@Measurement(iterations = 5)
+@Fork(2)
+public class V2CborProtocolBenchmark {
+
+ private static final String CONTENT_TYPE = "application/cbor";
+ private static final URI ENDPOINT = URI.create("http://localhost/");
+
+ private static final AwsJsonProtocolMetadata METADATA = AwsJsonProtocolMetadata.builder()
+ .protocol(AwsJsonProtocol.SMITHY_RPC_V2_CBOR)
+ .contentType(CONTENT_TYPE)
+ .build();
+
+ private static final OperationInfo OP_INFO = OperationInfo.builder()
+ .requestUri("/service/GraniteServiceVersion20100801/operation/GetMetricData")
+ .httpMethod(SdkHttpMethod.POST)
+ .hasExplicitPayloadMember(false)
+ .hasImplicitPayloadMembers(true)
+ .hasPayloadMembers(true)
+ .build();
+
+ private JsonProtocolUnmarshaller unmarshaller;
+ private byte[] responseBytes;
+ private GetMetricDataRequest request;
+
+ @Setup
+ public void setup() throws Exception {
+ unmarshaller = JsonProtocolUnmarshaller.builder()
+ .enableFastUnmarshalling(true)
+ .protocolUnmarshallDependencies(SmithyRpcV2CborProtocolFactory.defaultProtocolUnmarshallDependencies())
+ .build();
+
+ responseBytes = createCborResponseFixture();
+ request = createRequest();
+ }
+
+ @Benchmark
+ public void getMetricDataDeser(Blackhole bh) throws Exception {
+ SdkHttpFullResponse response = SdkHttpFullResponse.builder()
+ .statusCode(200)
+ .putHeader("Content-Type", CONTENT_TYPE)
+ .content(AbortableInputStream.create(new ByteArrayInputStream(responseBytes)))
+ .build();
+ bh.consume(unmarshaller.unmarshall(GetMetricDataResponse.builder(), response));
+ }
+
+ @Benchmark
+ public void getMetricDataSer(Blackhole bh) {
+ ProtocolMarshaller marshaller = JsonProtocolMarshallerBuilder.create()
+ .endpoint(ENDPOINT)
+ .jsonGenerator(SdkStructuredRpcV2CborFactory.SDK_CBOR_FACTORY.createWriter(CONTENT_TYPE))
+ .contentType(CONTENT_TYPE)
+ .operationInfo(OP_INFO)
+ .sendExplicitNullForPayload(false)
+ .protocolMetadata(METADATA)
+ .build();
+ bh.consume(marshaller.marshall(request));
+ }
+
+ private static GetMetricDataRequest createRequest() {
+ Instant end = Instant.parse("2026-03-09T00:00:00Z");
+ Instant start = end.minusSeconds(3600);
+ return GetMetricDataRequest.builder()
+ .startTime(start)
+ .endTime(end)
+ .maxDatapoints(1000)
+ .metricDataQueries(
+ MetricDataQuery.builder()
+ .id("cpu")
+ .metricStat(MetricStat.builder()
+ .metric(Metric.builder()
+ .namespace("AWS/EC2")
+ .metricName("CPUUtilization")
+ .build())
+ .period(300)
+ .stat("Average")
+ .build())
+ .returnData(true)
+ .build())
+ .build();
+ }
+
+ private static byte[] createCborResponseFixture() {
+ StructuredJsonGenerator gen =
+ SdkStructuredRpcV2CborFactory.SDK_CBOR_FACTORY.createWriter(CONTENT_TYPE);
+ gen.writeStartObject();
+ gen.writeFieldName("MetricDataResults");
+ gen.writeStartArray();
+ gen.writeStartObject();
+ gen.writeFieldName("Id");
+ gen.writeValue("cpu");
+ gen.writeFieldName("Label");
+ gen.writeValue("CPUUtilization");
+ gen.writeFieldName("StatusCode");
+ gen.writeValue("Complete");
+ gen.writeFieldName("Timestamps");
+ gen.writeStartArray();
+ long base = 1772611200L;
+ for (int i = 0; i < 12; i++) {
+ gen.writeValue((double) ((base + i * 300) * 1000));
+ }
+ gen.writeEndArray();
+ gen.writeFieldName("Values");
+ gen.writeStartArray();
+ for (int i = 0; i < 12; i++) {
+ gen.writeValue(45.2 + i * 1.1);
+ }
+ gen.writeEndArray();
+ gen.writeFieldName("Messages");
+ gen.writeStartArray();
+ gen.writeEndArray();
+ gen.writeEndObject();
+ gen.writeEndArray();
+ gen.writeFieldName("Messages");
+ gen.writeStartArray();
+ gen.writeEndArray();
+ gen.writeEndObject();
+ return gen.getBytes();
+ }
+}
diff --git a/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/protocol/V2Ec2ProtocolBenchmark.java b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/protocol/V2Ec2ProtocolBenchmark.java
new file mode 100644
index 000000000000..2f3beb03a466
--- /dev/null
+++ b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/protocol/V2Ec2ProtocolBenchmark.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License").
+ * You may not use this file except in compliance with the License.
+ * A copy of the License is located at
+ *
+ * http://aws.amazon.com/apache2.0
+ *
+ * or in the "license" file accompanying this file. This file is distributed
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+package software.amazon.awssdk.benchmark.protocol;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.net.URI;
+import java.util.concurrent.TimeUnit;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Fork;
+import org.openjdk.jmh.annotations.Measurement;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.annotations.Warmup;
+import org.openjdk.jmh.infra.Blackhole;
+import software.amazon.awssdk.http.AbortableInputStream;
+import software.amazon.awssdk.http.SdkHttpFullRequest;
+import software.amazon.awssdk.http.SdkHttpFullResponse;
+import software.amazon.awssdk.http.SdkHttpMethod;
+import software.amazon.awssdk.protocols.core.OperationInfo;
+import software.amazon.awssdk.protocols.core.ProtocolMarshaller;
+import software.amazon.awssdk.protocols.query.internal.marshall.QueryProtocolMarshaller;
+import software.amazon.awssdk.protocols.query.internal.unmarshall.QueryProtocolUnmarshaller;
+import software.amazon.awssdk.services.ec2.model.DescribeInstancesRequest;
+import software.amazon.awssdk.services.ec2.model.DescribeInstancesResponse;
+import software.amazon.awssdk.services.ec2.model.Filter;
+import software.amazon.awssdk.utils.Pair;
+
+/**
+ * Isolated ser/de benchmark for V2 EC2 (EC2 Query protocol).
+ * Measures only XML parsing + form encoding -- no HTTP, signing, or retries.
+ */
+@State(Scope.Benchmark)
+@BenchmarkMode(Mode.SampleTime)
+@OutputTimeUnit(TimeUnit.MICROSECONDS)
+@Warmup(iterations = 5)
+@Measurement(iterations = 5)
+@Fork(2)
+public class V2Ec2ProtocolBenchmark {
+
+ private static final URI ENDPOINT = URI.create("http://localhost/");
+ private static final OperationInfo OP_INFO = OperationInfo.builder()
+ .requestUri("/")
+ .httpMethod(SdkHttpMethod.POST)
+ .hasExplicitPayloadMember(false)
+ .hasPayloadMembers(true)
+ .operationIdentifier("DescribeInstances")
+ .apiVersion("2016-11-15")
+ .build();
+
+ private QueryProtocolUnmarshaller unmarshaller;
+ private byte[] responseBytes;
+ private DescribeInstancesRequest request;
+
+ @Setup
+ public void setup() throws Exception {
+ unmarshaller = QueryProtocolUnmarshaller.builder().hasResultWrapper(false).build();
+ responseBytes = loadFixture("fixtures/ec2-protocol/describe-instances-response.xml");
+ request = createRequest();
+ }
+
+ @Benchmark
+ public void describeInstancesDeser(Blackhole bh) {
+ SdkHttpFullResponse response = SdkHttpFullResponse.builder()
+ .statusCode(200)
+ .content(AbortableInputStream.create(new ByteArrayInputStream(responseBytes)))
+ .build();
+
+ Pair result = unmarshaller.unmarshall(DescribeInstancesResponse.builder(), response);
+ bh.consume(result.left());
+ }
+
+ @Benchmark
+ public void describeInstancesSer(Blackhole bh) {
+ ProtocolMarshaller marshaller = QueryProtocolMarshaller.builder()
+ .endpoint(ENDPOINT)
+ .operationInfo(OP_INFO)
+ .isEc2(true)
+ .build();
+ bh.consume(marshaller.marshall(request));
+ }
+
+ private static DescribeInstancesRequest createRequest() {
+ return DescribeInstancesRequest.builder()
+ .instanceIds("i-0abcdef1234567890")
+ .filters(
+ Filter.builder().name("instance-state-name")
+ .values("running").build(),
+ Filter.builder().name("instance-type")
+ .values("m5.xlarge").build())
+ .maxResults(100)
+ .build();
+ }
+
+ private static byte[] loadFixture(String path) throws IOException {
+ return software.amazon.awssdk.utils.IoUtils.toByteArray(
+ V2Ec2ProtocolBenchmark.class.getClassLoader()
+ .getResourceAsStream(path));
+ }
+}
diff --git a/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/protocol/V2JsonProtocolBenchmark.java b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/protocol/V2JsonProtocolBenchmark.java
new file mode 100644
index 000000000000..87ad57fd38fa
--- /dev/null
+++ b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/protocol/V2JsonProtocolBenchmark.java
@@ -0,0 +1,151 @@
+/*
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License").
+ * You may not use this file except in compliance with the License.
+ * A copy of the License is located at
+ *
+ * http://aws.amazon.com/apache2.0
+ *
+ * or in the "license" file accompanying this file. This file is distributed
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+package software.amazon.awssdk.benchmark.protocol;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.net.URI;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Fork;
+import org.openjdk.jmh.annotations.Measurement;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.annotations.Warmup;
+import org.openjdk.jmh.infra.Blackhole;
+import software.amazon.awssdk.core.SdkBytes;
+import software.amazon.awssdk.http.AbortableInputStream;
+import software.amazon.awssdk.http.SdkHttpFullRequest;
+import software.amazon.awssdk.http.SdkHttpFullResponse;
+import software.amazon.awssdk.http.SdkHttpMethod;
+import software.amazon.awssdk.protocols.core.OperationInfo;
+import software.amazon.awssdk.protocols.core.ProtocolMarshaller;
+import software.amazon.awssdk.protocols.json.AwsJsonProtocol;
+import software.amazon.awssdk.protocols.json.AwsJsonProtocolMetadata;
+import software.amazon.awssdk.protocols.json.internal.AwsStructuredPlainJsonFactory;
+import software.amazon.awssdk.protocols.json.internal.marshall.JsonProtocolMarshallerBuilder;
+import software.amazon.awssdk.protocols.json.internal.unmarshall.JsonProtocolUnmarshaller;
+import software.amazon.awssdk.services.dynamodb.model.AttributeValue;
+import software.amazon.awssdk.services.dynamodb.model.PutItemRequest;
+import software.amazon.awssdk.services.dynamodb.model.PutItemResponse;
+
+/**
+ * Isolated ser/de benchmark for V2 DynamoDB (JSON protocol).
+ * Measures only JSON parsing + object construction -- no HTTP, signing, or retries.
+ */
+@State(Scope.Benchmark)
+@BenchmarkMode(Mode.SampleTime)
+@OutputTimeUnit(TimeUnit.MICROSECONDS)
+@Warmup(iterations = 5)
+@Measurement(iterations = 5)
+@Fork(2)
+public class V2JsonProtocolBenchmark {
+
+ private static final String CONTENT_TYPE = "application/x-amz-json-1.0";
+ private static final URI ENDPOINT = URI.create("http://localhost/");
+ private static final OperationInfo OP_INFO = OperationInfo.builder()
+ .httpMethod(SdkHttpMethod.POST)
+ .hasImplicitPayloadMembers(true)
+ .build();
+
+ private static final AwsJsonProtocolMetadata METADATA = AwsJsonProtocolMetadata.builder()
+ .protocol(AwsJsonProtocol.AWS_JSON)
+ .contentType(CONTENT_TYPE)
+ .build();
+
+ private JsonProtocolUnmarshaller unmarshaller;
+ private byte[] putItemResponseBytes;
+ private PutItemRequest putItemRequest;
+
+ @Setup
+ public void setup() throws Exception {
+ unmarshaller = JsonProtocolUnmarshaller.builder()
+ .enableFastUnmarshalling(true)
+ .protocolUnmarshallDependencies(JsonProtocolUnmarshaller.defaultProtocolUnmarshallDependencies())
+ .build();
+
+ putItemResponseBytes = loadFixture("fixtures/json-protocol/putitem-response.json");
+ putItemRequest = PutItemRequest.builder()
+ .tableName("benchmark-table")
+ .item(itemMap())
+ .build();
+ }
+
+ @Benchmark
+ public void putItemDeser(Blackhole bh) throws Exception {
+ SdkHttpFullResponse response = SdkHttpFullResponse.builder()
+ .statusCode(200)
+ .putHeader("Content-Type", CONTENT_TYPE)
+ .content(AbortableInputStream.create(new ByteArrayInputStream(putItemResponseBytes)))
+ .build();
+
+ bh.consume(unmarshaller.unmarshall(PutItemResponse.builder(), response));
+ }
+
+ @Benchmark
+ public void putItemSer(Blackhole bh) {
+ ProtocolMarshaller marshaller = JsonProtocolMarshallerBuilder.create()
+ .endpoint(ENDPOINT)
+ .jsonGenerator(AwsStructuredPlainJsonFactory.SDK_JSON_FACTORY
+ .createWriter(CONTENT_TYPE))
+ .contentType(CONTENT_TYPE)
+ .operationInfo(OP_INFO)
+ .sendExplicitNullForPayload(false)
+ .protocolMetadata(METADATA)
+ .build();
+
+ bh.consume(marshaller.marshall(putItemRequest));
+ }
+
+ private static Map itemMap() {
+ Map item = new HashMap();
+ item.put("pk", AttributeValue.fromS("benchmark-key"));
+ item.put("sk", AttributeValue.fromN("100"));
+ item.put("stringField", AttributeValue.fromS("test-value"));
+ item.put("numberField", AttributeValue.fromN("123.456"));
+ item.put("binaryField", AttributeValue.fromB(
+ SdkBytes.fromByteArray("hello world".getBytes())));
+ item.put("stringSetField", AttributeValue.builder()
+ .ss("value1", "value2", "value3").build());
+ item.put("numberSetField", AttributeValue.builder()
+ .ns("1.1", "2.2", "3.3").build());
+ item.put("boolField", AttributeValue.fromBool(false));
+ item.put("nullField", AttributeValue.builder().nul(true).build());
+ Map deep = new HashMap();
+ deep.put("level2", AttributeValue.fromN("999"));
+ Map nested = new HashMap();
+ nested.put("nested", AttributeValue.fromS("nested-value"));
+ nested.put("deepNested", AttributeValue.fromM(deep));
+ item.put("mapField", AttributeValue.fromM(nested));
+ item.put("listField", AttributeValue.builder().l(
+ AttributeValue.fromS("item1"),
+ AttributeValue.fromN("42"),
+ AttributeValue.fromBool(true),
+ AttributeValue.builder().nul(true).build()).build());
+ return item;
+ }
+
+ private static byte[] loadFixture(String path) throws IOException {
+ return software.amazon.awssdk.utils.IoUtils.toByteArray(
+ V2JsonProtocolBenchmark.class.getClassLoader().getResourceAsStream(path));
+ }
+}
diff --git a/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/protocol/V2QueryProtocolBenchmark.java b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/protocol/V2QueryProtocolBenchmark.java
new file mode 100644
index 000000000000..1e6c6ac49b5d
--- /dev/null
+++ b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/protocol/V2QueryProtocolBenchmark.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License").
+ * You may not use this file except in compliance with the License.
+ * A copy of the License is located at
+ *
+ * http://aws.amazon.com/apache2.0
+ *
+ * or in the "license" file accompanying this file. This file is distributed
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+package software.amazon.awssdk.benchmark.protocol;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.net.URI;
+import java.util.concurrent.TimeUnit;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Fork;
+import org.openjdk.jmh.annotations.Measurement;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.annotations.Warmup;
+import org.openjdk.jmh.infra.Blackhole;
+import software.amazon.awssdk.http.AbortableInputStream;
+import software.amazon.awssdk.http.SdkHttpFullRequest;
+import software.amazon.awssdk.http.SdkHttpFullResponse;
+import software.amazon.awssdk.http.SdkHttpMethod;
+import software.amazon.awssdk.protocols.core.OperationInfo;
+import software.amazon.awssdk.protocols.core.ProtocolMarshaller;
+import software.amazon.awssdk.protocols.query.internal.marshall.QueryProtocolMarshaller;
+import software.amazon.awssdk.protocols.query.internal.unmarshall.QueryProtocolUnmarshaller;
+import software.amazon.awssdk.services.sts.model.AssumeRoleRequest;
+import software.amazon.awssdk.services.sts.model.AssumeRoleResponse;
+import software.amazon.awssdk.utils.Pair;
+
+/**
+ * Isolated ser/de benchmark for V2 STS (Query protocol).
+ * Measures only XML parsing + form encoding -- no HTTP, signing, or retries.
+ */
+@State(Scope.Benchmark)
+@BenchmarkMode(Mode.SampleTime)
+@OutputTimeUnit(TimeUnit.MICROSECONDS)
+@Warmup(iterations = 5)
+@Measurement(iterations = 5)
+@Fork(2)
+public class V2QueryProtocolBenchmark {
+
+ private static final URI ENDPOINT = URI.create("http://localhost/");
+ private static final OperationInfo OP_INFO = OperationInfo.builder()
+ .requestUri("/")
+ .httpMethod(SdkHttpMethod.POST)
+ .hasExplicitPayloadMember(false)
+ .hasPayloadMembers(true)
+ .operationIdentifier("AssumeRole")
+ .apiVersion("2011-06-15")
+ .build();
+
+ private QueryProtocolUnmarshaller unmarshaller;
+ private byte[] responseBytes;
+ private AssumeRoleRequest request;
+
+ @Setup
+ public void setup() throws Exception {
+ unmarshaller = QueryProtocolUnmarshaller.builder()
+ .hasResultWrapper(true)
+ .build();
+
+ responseBytes = loadFixture("fixtures/query-protocol/assumerole-response.xml");
+ request = createRequest();
+ }
+
+ @Benchmark
+ public void assumeRoleDeser(Blackhole bh) {
+ SdkHttpFullResponse response = SdkHttpFullResponse.builder()
+ .statusCode(200)
+ .content(AbortableInputStream.create(new ByteArrayInputStream(responseBytes)))
+ .build();
+
+ Pair result = unmarshaller.unmarshall(AssumeRoleResponse.builder(), response);
+ bh.consume(result.left());
+ }
+
+ @Benchmark
+ public void assumeRoleSer(Blackhole bh) {
+ ProtocolMarshaller marshaller = QueryProtocolMarshaller.builder()
+ .endpoint(ENDPOINT)
+ .operationInfo(OP_INFO)
+ .isEc2(false)
+ .build();
+ bh.consume(marshaller.marshall(request));
+ }
+
+ private static AssumeRoleRequest createRequest() {
+ return AssumeRoleRequest.builder()
+ .roleArn("arn:aws:iam::123456789012:role/benchmark-role")
+ .roleSessionName("benchmark-session")
+ .durationSeconds(3600)
+ .externalId("benchmark-external-id")
+ .policy("{\"Version\":\"2012-10-17\"}")
+ .build();
+ }
+
+ private static byte[] loadFixture(String path) throws IOException {
+ return software.amazon.awssdk.utils.IoUtils.toByteArray(
+ V2QueryProtocolBenchmark.class.getClassLoader()
+ .getResourceAsStream(path));
+ }
+}
diff --git a/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/protocol/V2RestJsonProtocolBenchmark.java b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/protocol/V2RestJsonProtocolBenchmark.java
new file mode 100644
index 000000000000..6f76afece417
--- /dev/null
+++ b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/protocol/V2RestJsonProtocolBenchmark.java
@@ -0,0 +1,153 @@
+/*
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License").
+ * You may not use this file except in compliance with the License.
+ * A copy of the License is located at
+ *
+ * http://aws.amazon.com/apache2.0
+ *
+ * or in the "license" file accompanying this file. This file is distributed
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+package software.amazon.awssdk.benchmark.protocol;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.net.URI;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Fork;
+import org.openjdk.jmh.annotations.Measurement;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.annotations.Warmup;
+import org.openjdk.jmh.infra.Blackhole;
+import software.amazon.awssdk.http.AbortableInputStream;
+import software.amazon.awssdk.http.SdkHttpFullRequest;
+import software.amazon.awssdk.http.SdkHttpFullResponse;
+import software.amazon.awssdk.http.SdkHttpMethod;
+import software.amazon.awssdk.protocols.core.OperationInfo;
+import software.amazon.awssdk.protocols.core.ProtocolMarshaller;
+import software.amazon.awssdk.protocols.json.AwsJsonProtocol;
+import software.amazon.awssdk.protocols.json.AwsJsonProtocolMetadata;
+import software.amazon.awssdk.protocols.json.internal.AwsStructuredPlainJsonFactory;
+import software.amazon.awssdk.protocols.json.internal.marshall.JsonProtocolMarshallerBuilder;
+import software.amazon.awssdk.protocols.json.internal.unmarshall.JsonProtocolUnmarshaller;
+import software.amazon.awssdk.services.lambda.model.CreateFunctionRequest;
+import software.amazon.awssdk.services.lambda.model.CreateFunctionResponse;
+import software.amazon.awssdk.services.lambda.model.Environment;
+import software.amazon.awssdk.services.lambda.model.FunctionCode;
+import software.amazon.awssdk.services.lambda.model.Runtime;
+import software.amazon.awssdk.services.lambda.model.TracingConfig;
+import software.amazon.awssdk.services.lambda.model.TracingMode;
+
+/**
+ * Isolated ser/de benchmark for V2 Lambda (REST-JSON protocol).
+ * Measures only JSON parsing + object construction -- no HTTP, signing, or retries.
+ */
+@State(Scope.Benchmark)
+@BenchmarkMode(Mode.SampleTime)
+@OutputTimeUnit(TimeUnit.MICROSECONDS)
+@Warmup(iterations = 5)
+@Measurement(iterations = 5)
+@Fork(2)
+public class V2RestJsonProtocolBenchmark {
+
+ private static final String CONTENT_TYPE = "application/json";
+ private static final URI ENDPOINT = URI.create("http://localhost/");
+ private static final OperationInfo OP_INFO = OperationInfo.builder()
+ .requestUri("/2015-03-31/functions")
+ .httpMethod(SdkHttpMethod.POST)
+ .hasExplicitPayloadMember(false)
+ .hasImplicitPayloadMembers(true)
+ .hasPayloadMembers(true)
+ .build();
+
+ private static final AwsJsonProtocolMetadata METADATA =
+ AwsJsonProtocolMetadata.builder()
+ .protocol(AwsJsonProtocol.REST_JSON)
+ .protocolVersion("1.1")
+ .contentType(CONTENT_TYPE)
+ .build();
+
+ private JsonProtocolUnmarshaller unmarshaller;
+ private byte[] responseBytes;
+ private CreateFunctionRequest request;
+
+ @Setup
+ public void setup() throws Exception {
+ unmarshaller = JsonProtocolUnmarshaller.builder()
+ .enableFastUnmarshalling(true)
+ .protocolUnmarshallDependencies(JsonProtocolUnmarshaller.defaultProtocolUnmarshallDependencies())
+ .build();
+
+ responseBytes = loadFixture("fixtures/rest-json-protocol/createfunction-response.json");
+ request = createRequest();
+ }
+
+ @Benchmark
+ public void createFunctionDeser(Blackhole bh) throws IOException {
+ SdkHttpFullResponse response = SdkHttpFullResponse.builder()
+ .statusCode(200)
+ .putHeader("Content-Type", CONTENT_TYPE)
+ .content(AbortableInputStream.create(
+ new ByteArrayInputStream(responseBytes)))
+ .build();
+ bh.consume(unmarshaller.unmarshall(CreateFunctionResponse.builder(), response));
+ }
+
+ @Benchmark
+ public void createFunctionSer(Blackhole bh) {
+ ProtocolMarshaller marshaller =
+ JsonProtocolMarshallerBuilder.create()
+ .endpoint(ENDPOINT)
+ .jsonGenerator(AwsStructuredPlainJsonFactory.SDK_JSON_FACTORY
+ .createWriter(CONTENT_TYPE))
+ .contentType(CONTENT_TYPE)
+ .operationInfo(OP_INFO)
+ .sendExplicitNullForPayload(false)
+ .protocolMetadata(METADATA)
+ .build();
+ bh.consume(marshaller.marshall(request));
+ }
+
+ private static CreateFunctionRequest createRequest() {
+ Map envVars = new HashMap<>();
+ envVars.put("ENV_VAR_1", "value1");
+
+ return CreateFunctionRequest.builder()
+ .functionName("benchmark-function")
+ .runtime(Runtime.JAVA8)
+ .role("arn:aws:iam::123456789012:role/lambda-role")
+ .handler("com.example.Handler::handleRequest")
+ .code(FunctionCode.builder()
+ .s3Bucket("my-deploy-bucket")
+ .s3Key("code/function.zip")
+ .build())
+ .description("Benchmark test function")
+ .timeout(30)
+ .memorySize(512)
+ .publish(false)
+ .environment(Environment.builder().variables(envVars).build())
+ .tracingConfig(TracingConfig.builder()
+ .mode(TracingMode.ACTIVE)
+ .build())
+ .build();
+ }
+
+ private static byte[] loadFixture(String path) throws IOException {
+ return software.amazon.awssdk.utils.IoUtils.toByteArray(
+ V2RestJsonProtocolBenchmark.class.getClassLoader()
+ .getResourceAsStream(path));
+ }
+}
diff --git a/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/protocol/V2RestXmlProtocolBenchmark.java b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/protocol/V2RestXmlProtocolBenchmark.java
new file mode 100644
index 000000000000..e2c61142c356
--- /dev/null
+++ b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/protocol/V2RestXmlProtocolBenchmark.java
@@ -0,0 +1,154 @@
+/*
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License").
+ * You may not use this file except in compliance with the License.
+ * A copy of the License is located at
+ *
+ * http://aws.amazon.com/apache2.0
+ *
+ * or in the "license" file accompanying this file. This file is distributed
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+package software.amazon.awssdk.benchmark.protocol;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.net.URI;
+import java.util.concurrent.TimeUnit;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Fork;
+import org.openjdk.jmh.annotations.Measurement;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.annotations.Warmup;
+import org.openjdk.jmh.infra.Blackhole;
+import software.amazon.awssdk.http.AbortableInputStream;
+import software.amazon.awssdk.http.SdkHttpFullRequest;
+import software.amazon.awssdk.http.SdkHttpFullResponse;
+import software.amazon.awssdk.http.SdkHttpMethod;
+import software.amazon.awssdk.protocols.core.OperationInfo;
+import software.amazon.awssdk.protocols.core.ProtocolMarshaller;
+import software.amazon.awssdk.protocols.xml.AwsXmlProtocolFactory;
+import software.amazon.awssdk.protocols.xml.internal.marshall.XmlGenerator;
+import software.amazon.awssdk.protocols.xml.internal.marshall.XmlProtocolMarshaller;
+import software.amazon.awssdk.protocols.xml.internal.unmarshall.XmlProtocolUnmarshaller;
+import software.amazon.awssdk.services.cloudfront.model.Aliases;
+import software.amazon.awssdk.services.cloudfront.model.AllowedMethods;
+import software.amazon.awssdk.services.cloudfront.model.CachedMethods;
+import software.amazon.awssdk.services.cloudfront.model.CreateDistributionRequest;
+import software.amazon.awssdk.services.cloudfront.model.CreateDistributionResponse;
+import software.amazon.awssdk.services.cloudfront.model.DefaultCacheBehavior;
+import software.amazon.awssdk.services.cloudfront.model.DistributionConfig;
+import software.amazon.awssdk.services.cloudfront.model.Method;
+import software.amazon.awssdk.services.cloudfront.model.Origin;
+import software.amazon.awssdk.services.cloudfront.model.Origins;
+import software.amazon.awssdk.services.cloudfront.model.S3OriginConfig;
+import software.amazon.awssdk.services.cloudfront.model.ViewerProtocolPolicy;
+
+/**
+ * Isolated ser/de benchmark for V2 CloudFront (REST-XML protocol).
+ * Measures only XML parsing + object construction -- no HTTP, signing, or retries.
+ */
+@State(Scope.Benchmark)
+@BenchmarkMode(Mode.SampleTime)
+@OutputTimeUnit(TimeUnit.MICROSECONDS)
+@Warmup(iterations = 5)
+@Measurement(iterations = 5)
+@Fork(2)
+public class V2RestXmlProtocolBenchmark {
+
+ private static final String XMLNS = "http://cloudfront.amazonaws.com/doc/2020-05-31/";
+ private static final URI ENDPOINT = URI.create("http://localhost/");
+ private static final OperationInfo OP_INFO = OperationInfo.builder()
+ .requestUri("/2020-05-31/distribution")
+ .httpMethod(SdkHttpMethod.POST)
+ .hasExplicitPayloadMember(true)
+ .hasPayloadMembers(true)
+ .putAdditionalMetadata(AwsXmlProtocolFactory.ROOT_MARSHALL_LOCATION_ATTRIBUTE, null)
+ .putAdditionalMetadata(AwsXmlProtocolFactory.XML_NAMESPACE_ATTRIBUTE, XMLNS)
+ .build();
+
+ private XmlProtocolUnmarshaller unmarshaller;
+ private byte[] responseBytes;
+ private CreateDistributionRequest request;
+
+ @Setup
+ public void setup() throws Exception {
+ unmarshaller = XmlProtocolUnmarshaller.create();
+ responseBytes = loadFixture("fixtures/rest-xml-protocol/create-distribution-response.xml");
+ request = createRequest();
+ }
+
+ @Benchmark
+ public void createDistributionDeser(Blackhole bh) {
+ SdkHttpFullResponse response = SdkHttpFullResponse.builder()
+ .statusCode(200)
+ .putHeader("ETag", "E2QWRUHEXAMPLE")
+ .putHeader("Location", "https://cloudfront.amazonaws.com/2020-05-31/distribution/EDFDVBD6EXAMPLE")
+ .content(AbortableInputStream.create(new ByteArrayInputStream(responseBytes)))
+ .build();
+ bh.consume(unmarshaller.unmarshall(CreateDistributionResponse.builder(), response));
+ }
+
+ @Benchmark
+ public void createDistributionSer(Blackhole bh) {
+ ProtocolMarshaller marshaller = XmlProtocolMarshaller.builder()
+ .endpoint(ENDPOINT)
+ .xmlGenerator(XmlGenerator.create(XMLNS, false))
+ .operationInfo(OP_INFO)
+ .build();
+ bh.consume(marshaller.marshall(request));
+ }
+
+ private static CreateDistributionRequest createRequest() {
+ return CreateDistributionRequest.builder()
+ .distributionConfig(DistributionConfig.builder()
+ .callerReference("benchmark-ref-2024")
+ .aliases(Aliases.builder()
+ .quantity(2)
+ .items("www.example.com", "cdn.example.com")
+ .build())
+ .defaultRootObject("index.html")
+ .origins(Origins.builder()
+ .quantity(1)
+ .items(Origin.builder()
+ .id("myS3Origin")
+ .domainName("mybucket.s3.amazonaws.com")
+ .originPath("/production")
+ .s3OriginConfig(S3OriginConfig.builder()
+ .originAccessIdentity(
+ "origin-access-identity/cloudfront/E127EXAMPLE51Z")
+ .build())
+ .build())
+ .build())
+ .defaultCacheBehavior(DefaultCacheBehavior.builder()
+ .targetOriginId("myS3Origin")
+ .viewerProtocolPolicy(ViewerProtocolPolicy.REDIRECT_TO_HTTPS)
+ .allowedMethods(AllowedMethods.builder()
+ .quantity(3)
+ .items(Method.GET, Method.HEAD, Method.OPTIONS)
+ .cachedMethods(CachedMethods.builder()
+ .quantity(2)
+ .items(Method.GET, Method.HEAD)
+ .build())
+ .build())
+ .compress(true)
+ .build())
+ .build())
+ .build();
+ }
+
+ private static byte[] loadFixture(String path) throws IOException {
+ return software.amazon.awssdk.utils.IoUtils.toByteArray(
+ V2RestXmlProtocolBenchmark.class.getClassLoader()
+ .getResourceAsStream(path));
+ }
+}
diff --git a/test/sdk-benchmarks/src/main/resources/fixtures/ec2-protocol/describe-instances-response.xml b/test/sdk-benchmarks/src/main/resources/fixtures/ec2-protocol/describe-instances-response.xml
new file mode 100644
index 000000000000..6a8153163fdb
--- /dev/null
+++ b/test/sdk-benchmarks/src/main/resources/fixtures/ec2-protocol/describe-instances-response.xml
@@ -0,0 +1,37 @@
+
+ 8f7724cf-496f-496e-8fe2-example
+
+ -
+ r-0abcdef1234567890
+ 123456789012
+
+
-
+ i-0abcdef1234567890
+ ami-0abcdef1234567890
+
16running
+ ip-10-0-0-1.ec2.internal
+ ec2-203-0-113-1.compute-1.amazonaws.com
+ m5.xlarge
+ 2024-01-15T10:30:00.000Z
+ us-east-1adefault
+ disabled
+ subnet-0abcdef1234567890
+ vpc-0abcdef1234567890
+ 10.0.0.1
+ 203.0.113.1
+ x86_64
+ ebs
+ /dev/xvda
+ hvm
+ xen
+
+ - Namebenchmark-instance
+ - Environmentproduction
+
+ true
+ true
+
+
+
+
+
diff --git a/test/sdk-benchmarks/src/main/resources/fixtures/json-protocol/putitem-response.json b/test/sdk-benchmarks/src/main/resources/fixtures/json-protocol/putitem-response.json
new file mode 100644
index 000000000000..df9f0e8ada3f
--- /dev/null
+++ b/test/sdk-benchmarks/src/main/resources/fixtures/json-protocol/putitem-response.json
@@ -0,0 +1,24 @@
+{
+ "Attributes": {
+ "pk": {"S": "benchmark-key"},
+ "sk": {"N": "100"},
+ "stringField": {"S": "test-value"},
+ "numberField": {"N": "123.456"},
+ "binaryField": {"B": "aGVsbG8gd29ybGQ="},
+ "stringSetField": {"SS": ["value1", "value2", "value3"]},
+ "numberSetField": {"NS": ["1.1", "2.2", "3.3"]},
+ "binarySetField": {"BS": ["YmluMQ==", "YmluMg=="]},
+ "mapField": {"M": {
+ "nested": {"S": "nested-value"},
+ "deepNested": {"M": {"level2": {"N": "999"}}}
+ }},
+ "listField": {"L": [
+ {"S": "item1"},
+ {"N": "42"},
+ {"BOOL": true},
+ {"NULL": true}
+ ]},
+ "nullField": {"NULL": true},
+ "boolField": {"BOOL": false}
+ }
+}
\ No newline at end of file
diff --git a/test/sdk-benchmarks/src/main/resources/fixtures/query-protocol/assumerole-response.xml b/test/sdk-benchmarks/src/main/resources/fixtures/query-protocol/assumerole-response.xml
new file mode 100644
index 000000000000..db2481e96745
--- /dev/null
+++ b/test/sdk-benchmarks/src/main/resources/fixtures/query-protocol/assumerole-response.xml
@@ -0,0 +1,19 @@
+
+
+
+ ASIAIOSFODNN7EXAMPLE
+ wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
+ FwoGZXIvYXdzEBYaDHqa0AP1
+ 2024-01-15T12:00:00Z
+
+
+ AROA3XFRBF23EXAMPLE:benchmark-session
+ arn:aws:sts::123456789012:assumed-role/benchmark-role/benchmark-session
+
+ 42
+ benchmark-source
+
+
+ c6104cbe-af31-11e0-8154-cde7cf80f29a
+
+
diff --git a/test/sdk-benchmarks/src/main/resources/fixtures/rest-json-protocol/createfunction-response.json b/test/sdk-benchmarks/src/main/resources/fixtures/rest-json-protocol/createfunction-response.json
new file mode 100644
index 000000000000..638c54e42837
--- /dev/null
+++ b/test/sdk-benchmarks/src/main/resources/fixtures/rest-json-protocol/createfunction-response.json
@@ -0,0 +1,43 @@
+{
+ "FunctionName": "benchmark-function",
+ "FunctionArn": "arn:aws:lambda:us-east-1:123456789012:function:benchmark-function",
+ "Runtime": "java21",
+ "Role": "arn:aws:iam::123456789012:role/lambda-role",
+ "Handler": "com.example.Handler::handleRequest",
+ "CodeSize": 5242880,
+ "Description": "Benchmark test function",
+ "Timeout": 30,
+ "MemorySize": 512,
+ "LastModified": "2024-01-15T10:30:00.000+0000",
+ "CodeSha256": "dGVzdGhhc2g=",
+ "Version": "$LATEST",
+ "Environment": {
+ "Variables": {
+ "ENV_VAR_1": "value1",
+ "ENV_VAR_2": "value2",
+ "TABLE_NAME": "my-table"
+ }
+ },
+ "TracingConfig": {
+ "Mode": "Active"
+ },
+ "RevisionId": "a1b2c3d4-5678-90ab-cdef-EXAMPLE11111",
+ "Layers": [
+ {
+ "Arn": "arn:aws:lambda:us-east-1:123456789012:layer:my-layer:3",
+ "CodeSize": 1048576,
+ "SigningProfileVersionArn": "arn:aws:signer:us-east-1:123456789012:/signing-profiles/MyProfile"
+ }
+ ],
+ "State": "Active",
+ "LastUpdateStatus": "Successful",
+ "PackageType": "Zip",
+ "Architectures": ["arm64"],
+ "EphemeralStorage": {
+ "Size": 1024
+ },
+ "LoggingConfig": {
+ "LogFormat": "JSON",
+ "LogGroup": "/aws/lambda/benchmark-function"
+ }
+}
diff --git a/test/sdk-benchmarks/src/main/resources/fixtures/rest-xml-protocol/create-distribution-response.xml b/test/sdk-benchmarks/src/main/resources/fixtures/rest-xml-protocol/create-distribution-response.xml
new file mode 100644
index 000000000000..1c88743e9b15
--- /dev/null
+++ b/test/sdk-benchmarks/src/main/resources/fixtures/rest-xml-protocol/create-distribution-response.xml
@@ -0,0 +1,209 @@
+
+
+ EDFDVBD6EXAMPLE
+ arn:aws:cloudfront::123456789012:distribution/EDFDVBD6EXAMPLE
+ Deployed
+ 2024-01-15T10:30:00Z
+ 0
+ d111111abcdef8.cloudfront.net
+
+ false
+ 0
+
+
+ false
+ 0
+
+
+ benchmark-ref-2024
+
+ 2
+
+ www.example.com
+ cdn.example.com
+
+
+ index.html
+
+ 2
+
+
+ myS3Origin
+ mybucket.s3.amazonaws.com
+ /production
+
+ 1
+
+
+ X-Custom-Header
+ benchmark-value
+
+
+
+
+ origin-access-identity/cloudfront/E127EXAMPLE51Z
+
+ 3
+ 10
+
+ true
+ us-east-1
+
+
+
+ myCustomOrigin
+ api.example.com
+
+
+ 0
+
+
+ 80
+ 443
+ https-only
+
+ 1
+
+ TLSv1.2
+
+
+ 30
+ 5
+
+ 3
+ 10
+
+
+
+
+ myS3Origin
+
+ false
+ 0
+
+
+ false
+ 0
+
+ redirect-to-https
+
+ 3
+
+ GET
+ HEAD
+ OPTIONS
+
+
+ 2
+
+ GET
+ HEAD
+
+
+
+ false
+ true
+
+ 0
+
+
+ 0
+
+
+ 658327ea-f89d-4fab-a63d-7e88639e58f6
+
+
+ 1
+
+
+ /api/*
+ myCustomOrigin
+
+ false
+ 0
+
+
+ false
+ 0
+
+ https-only
+
+ 7
+
+ GET
+ HEAD
+ OPTIONS
+ PUT
+ POST
+ PATCH
+ DELETE
+
+
+ 2
+
+ GET
+ HEAD
+
+
+
+ false
+ true
+
+ 0
+
+
+ 0
+
+
+ 4135ea2d-6df8-44a3-9df3-4b5a84be39ad
+ 88a5eaf4-2fd4-4709-b370-b4c650ea3fcf
+
+
+
+
+ 2
+
+
+ 404
+ /errors/404.html
+ 404
+ 300
+
+
+ 500
+ /errors/500.html
+ 500
+ 60
+
+
+
+ Benchmark distribution
+
+ true
+ false
+ mylogs.s3.amazonaws.com
+ cf-logs/
+
+ PriceClass_100
+ true
+
+ arn:aws:acm:us-east-1:123456789012:certificate/abcd-1234
+ sni-only
+ TLSv1.2_2021
+
+
+
+ whitelist
+ 3
+
+ US
+ CA
+ GB
+
+
+
+
+ http2
+ true
+
+
From 5c6e7946e7221ed1fbcdc3bc5f5d8de0f1c0bcca Mon Sep 17 00:00:00 2001
From: RanVaknin <50976344+RanVaknin@users.noreply.github.com>
Date: Tue, 10 Mar 2026 22:47:07 -0700
Subject: [PATCH 2/7] Change benchmark mode to throughput
---
.../awssdk/benchmark/protocol/V1CborProtocolBenchmark.java | 6 +-----
.../awssdk/benchmark/protocol/V1Ec2ProtocolBenchmark.java | 6 +-----
.../awssdk/benchmark/protocol/V1JsonProtocolBenchmark.java | 6 +-----
.../awssdk/benchmark/protocol/V1QueryProtocolBenchmark.java | 6 +-----
.../benchmark/protocol/V1RestJsonProtocolBenchmark.java | 6 +-----
.../benchmark/protocol/V1RestXmlProtocolBenchmark.java | 6 +-----
.../awssdk/benchmark/protocol/V2CborProtocolBenchmark.java | 6 +-----
.../awssdk/benchmark/protocol/V2Ec2ProtocolBenchmark.java | 6 +-----
.../awssdk/benchmark/protocol/V2JsonProtocolBenchmark.java | 6 +-----
.../awssdk/benchmark/protocol/V2QueryProtocolBenchmark.java | 6 +-----
.../benchmark/protocol/V2RestJsonProtocolBenchmark.java | 6 +-----
.../benchmark/protocol/V2RestXmlProtocolBenchmark.java | 6 +-----
12 files changed, 12 insertions(+), 60 deletions(-)
diff --git a/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/protocol/V1CborProtocolBenchmark.java b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/protocol/V1CborProtocolBenchmark.java
index 5b0e1e59a3dc..2214d797edbf 100644
--- a/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/protocol/V1CborProtocolBenchmark.java
+++ b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/protocol/V1CborProtocolBenchmark.java
@@ -42,12 +42,8 @@
import org.openjdk.jmh.annotations.Warmup;
import org.openjdk.jmh.infra.Blackhole;
-/**
- * Isolated ser/de benchmark for V1 CloudWatch (smithy-rpc-v2-cbor protocol).
- * Measures only CBOR parsing + object construction -- no HTTP, signing, or retries.
- */
@State(Scope.Benchmark)
-@BenchmarkMode(Mode.SampleTime)
+@BenchmarkMode(Mode.Throughput)
@OutputTimeUnit(TimeUnit.MICROSECONDS)
@Warmup(iterations = 5)
@Measurement(iterations = 5)
diff --git a/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/protocol/V1Ec2ProtocolBenchmark.java b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/protocol/V1Ec2ProtocolBenchmark.java
index 82d8e01d7bd7..9435f5c5c218 100644
--- a/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/protocol/V1Ec2ProtocolBenchmark.java
+++ b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/protocol/V1Ec2ProtocolBenchmark.java
@@ -39,12 +39,8 @@
import org.openjdk.jmh.annotations.Warmup;
import org.openjdk.jmh.infra.Blackhole;
-/**
- * Isolated ser/de benchmark for V1 EC2 (EC2 Query protocol).
- * Measures only XML parsing + form encoding -- no HTTP, signing, or retries.
- */
@State(Scope.Benchmark)
-@BenchmarkMode(Mode.SampleTime)
+@BenchmarkMode(Mode.Throughput)
@OutputTimeUnit(TimeUnit.MICROSECONDS)
@Warmup(iterations = 5)
@Measurement(iterations = 5)
diff --git a/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/protocol/V1JsonProtocolBenchmark.java b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/protocol/V1JsonProtocolBenchmark.java
index 5cf300685a02..aee02c72626a 100644
--- a/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/protocol/V1JsonProtocolBenchmark.java
+++ b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/protocol/V1JsonProtocolBenchmark.java
@@ -44,12 +44,8 @@
import org.openjdk.jmh.annotations.Warmup;
import org.openjdk.jmh.infra.Blackhole;
-/**
- * Isolated ser/de benchmark for V1 DynamoDB (JSON protocol).
- * Measures only JSON parsing + object construction -- no HTTP, signing, or retries.
- */
@State(Scope.Benchmark)
-@BenchmarkMode(Mode.SampleTime)
+@BenchmarkMode(Mode.Throughput)
@OutputTimeUnit(TimeUnit.MICROSECONDS)
@Warmup(iterations = 5)
@Measurement(iterations = 5)
diff --git a/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/protocol/V1QueryProtocolBenchmark.java b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/protocol/V1QueryProtocolBenchmark.java
index 1f004d209b85..9e3ca35ad618 100644
--- a/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/protocol/V1QueryProtocolBenchmark.java
+++ b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/protocol/V1QueryProtocolBenchmark.java
@@ -38,12 +38,8 @@
import org.openjdk.jmh.annotations.Warmup;
import org.openjdk.jmh.infra.Blackhole;
-/**
- * Isolated ser/de benchmark for V1 STS (Query protocol).
- * Measures only XML parsing + form encoding -- no HTTP, signing, or retries.
- */
@State(Scope.Benchmark)
-@BenchmarkMode(Mode.SampleTime)
+@BenchmarkMode(Mode.Throughput)
@OutputTimeUnit(TimeUnit.MICROSECONDS)
@Warmup(iterations = 5)
@Measurement(iterations = 5)
diff --git a/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/protocol/V1RestJsonProtocolBenchmark.java b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/protocol/V1RestJsonProtocolBenchmark.java
index c2a48bd076d2..47da0763a6ac 100644
--- a/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/protocol/V1RestJsonProtocolBenchmark.java
+++ b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/protocol/V1RestJsonProtocolBenchmark.java
@@ -47,12 +47,8 @@
import org.openjdk.jmh.annotations.Warmup;
import org.openjdk.jmh.infra.Blackhole;
-/**
- * Isolated ser/de benchmark for V1 Lambda (REST-JSON protocol).
- * Measures only JSON parsing + object construction -- no HTTP, signing, or retries.
- */
@State(Scope.Benchmark)
-@BenchmarkMode(Mode.SampleTime)
+@BenchmarkMode(Mode.Throughput)
@OutputTimeUnit(TimeUnit.MICROSECONDS)
@Warmup(iterations = 5)
@Measurement(iterations = 5)
diff --git a/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/protocol/V1RestXmlProtocolBenchmark.java b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/protocol/V1RestXmlProtocolBenchmark.java
index bca728d7ef52..b5b7f578992e 100644
--- a/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/protocol/V1RestXmlProtocolBenchmark.java
+++ b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/protocol/V1RestXmlProtocolBenchmark.java
@@ -49,12 +49,8 @@
import org.openjdk.jmh.annotations.Warmup;
import org.openjdk.jmh.infra.Blackhole;
-/**
- * Isolated ser/de benchmark for V1 CloudFront (REST-XML protocol).
- * Measures only XML parsing + object construction -- no HTTP, signing, or retries.
- */
@State(Scope.Benchmark)
-@BenchmarkMode(Mode.SampleTime)
+@BenchmarkMode(Mode.Throughput)
@OutputTimeUnit(TimeUnit.MICROSECONDS)
@Warmup(iterations = 5)
@Measurement(iterations = 5)
diff --git a/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/protocol/V2CborProtocolBenchmark.java b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/protocol/V2CborProtocolBenchmark.java
index fd0ed68839e0..4f2785ee156b 100644
--- a/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/protocol/V2CborProtocolBenchmark.java
+++ b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/protocol/V2CborProtocolBenchmark.java
@@ -49,12 +49,8 @@
import software.amazon.awssdk.services.cloudwatch.model.MetricDataQuery;
import software.amazon.awssdk.services.cloudwatch.model.MetricStat;
-/**
- * Isolated ser/de benchmark for V2 CloudWatch (smithy-rpc-v2-cbor protocol).
- * Measures only CBOR parsing + object construction -- no HTTP, signing, or retries.
- */
@State(Scope.Benchmark)
-@BenchmarkMode(Mode.SampleTime)
+@BenchmarkMode(Mode.Throughput)
@OutputTimeUnit(TimeUnit.MICROSECONDS)
@Warmup(iterations = 5)
@Measurement(iterations = 5)
diff --git a/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/protocol/V2Ec2ProtocolBenchmark.java b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/protocol/V2Ec2ProtocolBenchmark.java
index 2f3beb03a466..677772608ac7 100644
--- a/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/protocol/V2Ec2ProtocolBenchmark.java
+++ b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/protocol/V2Ec2ProtocolBenchmark.java
@@ -43,12 +43,8 @@
import software.amazon.awssdk.services.ec2.model.Filter;
import software.amazon.awssdk.utils.Pair;
-/**
- * Isolated ser/de benchmark for V2 EC2 (EC2 Query protocol).
- * Measures only XML parsing + form encoding -- no HTTP, signing, or retries.
- */
@State(Scope.Benchmark)
-@BenchmarkMode(Mode.SampleTime)
+@BenchmarkMode(Mode.Throughput)
@OutputTimeUnit(TimeUnit.MICROSECONDS)
@Warmup(iterations = 5)
@Measurement(iterations = 5)
diff --git a/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/protocol/V2JsonProtocolBenchmark.java b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/protocol/V2JsonProtocolBenchmark.java
index 87ad57fd38fa..1983abf9a931 100644
--- a/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/protocol/V2JsonProtocolBenchmark.java
+++ b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/protocol/V2JsonProtocolBenchmark.java
@@ -48,12 +48,8 @@
import software.amazon.awssdk.services.dynamodb.model.PutItemRequest;
import software.amazon.awssdk.services.dynamodb.model.PutItemResponse;
-/**
- * Isolated ser/de benchmark for V2 DynamoDB (JSON protocol).
- * Measures only JSON parsing + object construction -- no HTTP, signing, or retries.
- */
@State(Scope.Benchmark)
-@BenchmarkMode(Mode.SampleTime)
+@BenchmarkMode(Mode.Throughput)
@OutputTimeUnit(TimeUnit.MICROSECONDS)
@Warmup(iterations = 5)
@Measurement(iterations = 5)
diff --git a/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/protocol/V2QueryProtocolBenchmark.java b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/protocol/V2QueryProtocolBenchmark.java
index 1e6c6ac49b5d..6d902e72fb5f 100644
--- a/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/protocol/V2QueryProtocolBenchmark.java
+++ b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/protocol/V2QueryProtocolBenchmark.java
@@ -42,12 +42,8 @@
import software.amazon.awssdk.services.sts.model.AssumeRoleResponse;
import software.amazon.awssdk.utils.Pair;
-/**
- * Isolated ser/de benchmark for V2 STS (Query protocol).
- * Measures only XML parsing + form encoding -- no HTTP, signing, or retries.
- */
@State(Scope.Benchmark)
-@BenchmarkMode(Mode.SampleTime)
+@BenchmarkMode(Mode.Throughput)
@OutputTimeUnit(TimeUnit.MICROSECONDS)
@Warmup(iterations = 5)
@Measurement(iterations = 5)
diff --git a/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/protocol/V2RestJsonProtocolBenchmark.java b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/protocol/V2RestJsonProtocolBenchmark.java
index 6f76afece417..1f090b87b629 100644
--- a/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/protocol/V2RestJsonProtocolBenchmark.java
+++ b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/protocol/V2RestJsonProtocolBenchmark.java
@@ -51,12 +51,8 @@
import software.amazon.awssdk.services.lambda.model.TracingConfig;
import software.amazon.awssdk.services.lambda.model.TracingMode;
-/**
- * Isolated ser/de benchmark for V2 Lambda (REST-JSON protocol).
- * Measures only JSON parsing + object construction -- no HTTP, signing, or retries.
- */
@State(Scope.Benchmark)
-@BenchmarkMode(Mode.SampleTime)
+@BenchmarkMode(Mode.Throughput)
@OutputTimeUnit(TimeUnit.MICROSECONDS)
@Warmup(iterations = 5)
@Measurement(iterations = 5)
diff --git a/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/protocol/V2RestXmlProtocolBenchmark.java b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/protocol/V2RestXmlProtocolBenchmark.java
index e2c61142c356..171099bd1be6 100644
--- a/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/protocol/V2RestXmlProtocolBenchmark.java
+++ b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/protocol/V2RestXmlProtocolBenchmark.java
@@ -53,12 +53,8 @@
import software.amazon.awssdk.services.cloudfront.model.S3OriginConfig;
import software.amazon.awssdk.services.cloudfront.model.ViewerProtocolPolicy;
-/**
- * Isolated ser/de benchmark for V2 CloudFront (REST-XML protocol).
- * Measures only XML parsing + object construction -- no HTTP, signing, or retries.
- */
@State(Scope.Benchmark)
-@BenchmarkMode(Mode.SampleTime)
+@BenchmarkMode(Mode.Throughput)
@OutputTimeUnit(TimeUnit.MICROSECONDS)
@Warmup(iterations = 5)
@Measurement(iterations = 5)
From 0537ec736ad474e5946d08e411a6d06c2de70584 Mon Sep 17 00:00:00 2001
From: RanVaknin <50976344+RanVaknin@users.noreply.github.com>
Date: Wed, 11 Mar 2026 13:45:54 -0700
Subject: [PATCH 3/7] Fix inconsistencies, checkstyle suppressions
---
.../software/amazon/awssdk/checkstyle-suppressions.xml | 2 +-
.../awssdk/benchmark/protocol/V2RestJsonProtocolBenchmark.java | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/build-tools/src/main/resources/software/amazon/awssdk/checkstyle-suppressions.xml b/build-tools/src/main/resources/software/amazon/awssdk/checkstyle-suppressions.xml
index ab1f3ade8258..2a6e22ef28ba 100644
--- a/build-tools/src/main/resources/software/amazon/awssdk/checkstyle-suppressions.xml
+++ b/build-tools/src/main/resources/software/amazon/awssdk/checkstyle-suppressions.xml
@@ -52,7 +52,7 @@
+ files=".*benchmark[\\/]protocol[\\/]V1.*\.java$"/>
Date: Mon, 16 Mar 2026 15:52:38 -0700
Subject: [PATCH 4/7] Add http servlet roundtrip benchmarks
---
.../protocol/ProtocolRoundtripServer.java | 70 +++++++++
.../protocol/ProtocolRoundtripServlet.java | 131 ++++++++++++++++
.../protocol/V1CborRoundtripBenchmark.java | 142 +++++++++++++++++
.../protocol/V1Ec2RoundtripBenchmark.java | 89 +++++++++++
.../protocol/V1JsonRoundtripBenchmark.java | 114 ++++++++++++++
.../protocol/V1QueryRoundtripBenchmark.java | 88 +++++++++++
.../V1RestJsonRoundtripBenchmark.java | 106 +++++++++++++
.../protocol/V1RestXmlRoundtripBenchmark.java | 120 ++++++++++++++
.../protocol/V2CborRoundtripBenchmark.java | 147 ++++++++++++++++++
.../protocol/V2Ec2RoundtripBenchmark.java | 91 +++++++++++
.../protocol/V2JsonRoundtripBenchmark.java | 116 ++++++++++++++
.../protocol/V2QueryRoundtripBenchmark.java | 90 +++++++++++
.../V2RestJsonRoundtripBenchmark.java | 109 +++++++++++++
.../protocol/V2RestXmlRoundtripBenchmark.java | 130 ++++++++++++++++
14 files changed, 1543 insertions(+)
create mode 100644 test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/ProtocolRoundtripServer.java
create mode 100644 test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/ProtocolRoundtripServlet.java
create mode 100644 test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V1CborRoundtripBenchmark.java
create mode 100644 test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V1Ec2RoundtripBenchmark.java
create mode 100644 test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V1JsonRoundtripBenchmark.java
create mode 100644 test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V1QueryRoundtripBenchmark.java
create mode 100644 test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V1RestJsonRoundtripBenchmark.java
create mode 100644 test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V1RestXmlRoundtripBenchmark.java
create mode 100644 test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V2CborRoundtripBenchmark.java
create mode 100644 test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V2Ec2RoundtripBenchmark.java
create mode 100644 test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V2JsonRoundtripBenchmark.java
create mode 100644 test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V2QueryRoundtripBenchmark.java
create mode 100644 test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V2RestJsonRoundtripBenchmark.java
create mode 100644 test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V2RestXmlRoundtripBenchmark.java
diff --git a/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/ProtocolRoundtripServer.java b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/ProtocolRoundtripServer.java
new file mode 100644
index 000000000000..96911c4e9442
--- /dev/null
+++ b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/ProtocolRoundtripServer.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License").
+ * You may not use this file except in compliance with the License.
+ * A copy of the License is located at
+ *
+ * http://aws.amazon.com/apache2.0
+ *
+ * or in the "license" file accompanying this file. This file is distributed
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+package software.amazon.awssdk.benchmark.apicall.protocol;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URI;
+import org.eclipse.jetty.server.Connector;
+import org.eclipse.jetty.server.Server;
+import org.eclipse.jetty.server.ServerConnector;
+import org.eclipse.jetty.servlet.ServletContextHandler;
+import org.eclipse.jetty.servlet.ServletHolder;
+import software.amazon.awssdk.benchmark.utils.BenchmarkUtils;
+import software.amazon.awssdk.utils.IoUtils;
+
+/**
+ * Lightweight Jetty server for protocol roundtrip benchmarks.
+ */
+class ProtocolRoundtripServer {
+
+ private final Server server;
+ private final int port;
+
+ ProtocolRoundtripServer(ProtocolRoundtripServlet servlet) throws IOException {
+ port = BenchmarkUtils.getUnusedPort();
+ server = new Server();
+ ServerConnector connector = new ServerConnector(server);
+ connector.setPort(port);
+ server.setConnectors(new Connector[] {connector});
+
+ ServletContextHandler context = new ServletContextHandler(server, "/", ServletContextHandler.SESSIONS);
+ context.addServlet(new ServletHolder(servlet), "/*");
+ server.setHandler(context);
+ }
+
+ void start() throws Exception {
+ server.start();
+ }
+
+ void stop() throws Exception {
+ server.stop();
+ }
+
+ URI getHttpUri() {
+ return URI.create("http://localhost:" + port);
+ }
+
+ static byte[] loadFixture(String path) throws IOException {
+ try (InputStream is = ProtocolRoundtripServer.class.getClassLoader()
+ .getResourceAsStream("fixtures/" + path)) {
+ if (is == null) {
+ throw new IOException("Fixture not found: fixtures/" + path);
+ }
+ return IoUtils.toByteArray(is);
+ }
+ }
+}
diff --git a/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/ProtocolRoundtripServlet.java b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/ProtocolRoundtripServlet.java
new file mode 100644
index 000000000000..dd2a97f14ddb
--- /dev/null
+++ b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/ProtocolRoundtripServlet.java
@@ -0,0 +1,131 @@
+/*
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License").
+ * You may not use this file except in compliance with the License.
+ * A copy of the License is located at
+ *
+ * http://aws.amazon.com/apache2.0
+ *
+ * or in the "license" file accompanying this file. This file is distributed
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+package software.amazon.awssdk.benchmark.apicall.protocol;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+/**
+ * Minimal servlet for protocol roundtrip benchmarks. Returns pre-loaded canned responses
+ * with zero request inspection overhead. Routes are matched by URI prefix or X-Amz-Target header.
+ */
+class ProtocolRoundtripServlet extends HttpServlet {
+
+ private final Map targetRoutes = new ConcurrentHashMap<>();
+ private final Map uriRoutes = new ConcurrentHashMap<>();
+ private CannedResponse defaultResponse;
+
+ /**
+ * Register a route matched by X-Amz-Target header value.
+ */
+ ProtocolRoundtripServlet routeByTarget(String target, String contentType, byte[] body) {
+ targetRoutes.put(target, new CannedResponse(contentType, body));
+ return this;
+ }
+
+ /**
+ * Register a route matched by URI prefix.
+ */
+ ProtocolRoundtripServlet routeByUri(String uriPrefix, String contentType, byte[] body) {
+ uriRoutes.put(uriPrefix, new CannedResponse(contentType, body));
+ return this;
+ }
+
+ /**
+ * Register a route matched by URI prefix with additional response headers.
+ */
+ ProtocolRoundtripServlet routeByUri(String uriPrefix, String contentType, byte[] body,
+ Map headers) {
+ uriRoutes.put(uriPrefix, new CannedResponse(contentType, body, headers));
+ return this;
+ }
+
+ /**
+ * Default response when no route matches.
+ */
+ ProtocolRoundtripServlet defaultRoute(String contentType, byte[] body) {
+ this.defaultResponse = new CannedResponse(contentType, body);
+ return this;
+ }
+
+ @Override
+ protected void service(HttpServletRequest req, HttpServletResponse resp) throws IOException {
+ // Consume request body to simulate real HTTP exchange
+ byte[] buf = new byte[8192];
+ while (req.getInputStream().read(buf) != -1) {
+ // drain
+ }
+
+ CannedResponse canned = resolve(req);
+ if (canned == null) {
+ resp.sendError(404);
+ return;
+ }
+
+ resp.setStatus(200);
+ resp.setContentType(canned.contentType);
+ resp.setContentLength(canned.body.length);
+ resp.setHeader("x-amzn-RequestId", "benchmark-request-id");
+ if (canned.headers != null) {
+ canned.headers.forEach(resp::setHeader);
+ }
+ try (OutputStream os = resp.getOutputStream()) {
+ os.write(canned.body);
+ }
+ }
+
+ private CannedResponse resolve(HttpServletRequest req) {
+ // Try X-Amz-Target first (JSON/CBOR protocols)
+ String target = req.getHeader("X-Amz-Target");
+ if (target != null) {
+ CannedResponse r = targetRoutes.get(target);
+ if (r != null) {
+ return r;
+ }
+ }
+
+ // Try URI prefix match (REST protocols)
+ String uri = req.getRequestURI();
+ for (Map.Entry entry : uriRoutes.entrySet()) {
+ if (uri.contains(entry.getKey())) {
+ return entry.getValue();
+ }
+ }
+
+ return defaultResponse;
+ }
+
+ private static class CannedResponse {
+ final String contentType;
+ final byte[] body;
+ final Map headers;
+
+ CannedResponse(String contentType, byte[] body) {
+ this(contentType, body, null);
+ }
+
+ CannedResponse(String contentType, byte[] body, Map headers) {
+ this.contentType = contentType;
+ this.body = body;
+ this.headers = headers;
+ }
+ }
+}
diff --git a/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V1CborRoundtripBenchmark.java b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V1CborRoundtripBenchmark.java
new file mode 100644
index 000000000000..1e2e369e1e49
--- /dev/null
+++ b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V1CborRoundtripBenchmark.java
@@ -0,0 +1,142 @@
+/*
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License").
+ * You may not use this file except in compliance with the License.
+ * A copy of the License is located at
+ *
+ * http://aws.amazon.com/apache2.0
+ *
+ * or in the "license" file accompanying this file. This file is distributed
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+package software.amazon.awssdk.benchmark.apicall.protocol;
+
+import com.amazonaws.auth.AWSStaticCredentialsProvider;
+import com.amazonaws.auth.BasicAWSCredentials;
+import com.amazonaws.client.builder.AwsClientBuilder;
+import com.amazonaws.protocol.rpcv2cbor.SdkStructuredCborFactory;
+import com.amazonaws.protocol.rpcv2cbor.StructuredRpcV2CborGenerator;
+import com.amazonaws.services.cloudwatch.AmazonCloudWatch;
+import com.amazonaws.services.cloudwatch.AmazonCloudWatchClientBuilder;
+import com.amazonaws.services.cloudwatch.model.GetMetricDataRequest;
+import com.amazonaws.services.cloudwatch.model.Metric;
+import com.amazonaws.services.cloudwatch.model.MetricDataQuery;
+import com.amazonaws.services.cloudwatch.model.MetricStat;
+import java.util.Date;
+import java.util.concurrent.TimeUnit;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Fork;
+import org.openjdk.jmh.annotations.Level;
+import org.openjdk.jmh.annotations.Measurement;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.annotations.TearDown;
+import org.openjdk.jmh.annotations.Warmup;
+import org.openjdk.jmh.infra.Blackhole;
+
+/**
+ * V1 roundtrip benchmark for SmithyRpcV2 CBOR protocol using CloudWatch GetMetricData via HTTP servlet.
+ */
+@State(Scope.Benchmark)
+@Warmup(iterations = 5)
+@Measurement(iterations = 5)
+@Fork(2)
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.MICROSECONDS)
+public class V1CborRoundtripBenchmark {
+
+ private ProtocolRoundtripServer server;
+ private AmazonCloudWatch client;
+ private GetMetricDataRequest request;
+
+ @Setup(Level.Trial)
+ public void setup() throws Exception {
+ byte[] response = createCborResponseFixture();
+
+ ProtocolRoundtripServlet servlet = new ProtocolRoundtripServlet()
+ .defaultRoute("application/cbor", response);
+
+ server = new ProtocolRoundtripServer(servlet);
+ server.start();
+
+ client = AmazonCloudWatchClientBuilder.standard()
+ .withEndpointConfiguration(new AwsClientBuilder.EndpointConfiguration(
+ server.getHttpUri().toString(), "us-east-1"))
+ .withCredentials(new AWSStaticCredentialsProvider(new BasicAWSCredentials("test", "test")))
+ .build();
+
+ Date end = Date.from(java.time.Instant.parse("2026-03-09T00:00:00Z"));
+ Date start = Date.from(java.time.Instant.parse("2026-03-09T00:00:00Z").minusSeconds(3600));
+ request = new GetMetricDataRequest()
+ .withStartTime(start)
+ .withEndTime(end)
+ .withMaxDatapoints(1000)
+ .withMetricDataQueries(
+ new MetricDataQuery()
+ .withId("cpu")
+ .withMetricStat(new MetricStat()
+ .withMetric(new Metric()
+ .withNamespace("AWS/EC2")
+ .withMetricName("CPUUtilization"))
+ .withPeriod(300)
+ .withStat("Average"))
+ .withReturnData(true));
+ }
+
+ @TearDown(Level.Trial)
+ public void tearDown() throws Exception {
+ client.shutdown();
+ server.stop();
+ }
+
+ @Benchmark
+ public void getMetricData(Blackhole bh) {
+ bh.consume(client.getMetricData(request));
+ }
+
+ private static byte[] createCborResponseFixture() {
+ StructuredRpcV2CborGenerator gen =
+ SdkStructuredCborFactory.SDK_CBOR_FACTORY.createWriter("application/cbor");
+ gen.writeStartObject();
+ gen.writeFieldName("MetricDataResults");
+ gen.writeStartArray();
+ gen.writeStartObject();
+ gen.writeFieldName("Id");
+ gen.writeValue("cpu");
+ gen.writeFieldName("Label");
+ gen.writeValue("CPUUtilization");
+ gen.writeFieldName("StatusCode");
+ gen.writeValue("Complete");
+ gen.writeFieldName("Timestamps");
+ gen.writeStartArray();
+ long base = 1772611200L;
+ for (int i = 0; i < 12; i++) {
+ gen.writeValue((double) ((base + i * 300) * 1000));
+ }
+ gen.writeEndArray();
+ gen.writeFieldName("Values");
+ gen.writeStartArray();
+ for (int i = 0; i < 12; i++) {
+ gen.writeValue(45.2 + i * 1.1);
+ }
+ gen.writeEndArray();
+ gen.writeFieldName("Messages");
+ gen.writeStartArray();
+ gen.writeEndArray();
+ gen.writeEndObject();
+ gen.writeEndArray();
+ gen.writeFieldName("Messages");
+ gen.writeStartArray();
+ gen.writeEndArray();
+ gen.writeEndObject();
+ return gen.getBytes();
+ }
+}
diff --git a/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V1Ec2RoundtripBenchmark.java b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V1Ec2RoundtripBenchmark.java
new file mode 100644
index 000000000000..ebe47b85a100
--- /dev/null
+++ b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V1Ec2RoundtripBenchmark.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License").
+ * You may not use this file except in compliance with the License.
+ * A copy of the License is located at
+ *
+ * http://aws.amazon.com/apache2.0
+ *
+ * or in the "license" file accompanying this file. This file is distributed
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+package software.amazon.awssdk.benchmark.apicall.protocol;
+
+import com.amazonaws.auth.AWSStaticCredentialsProvider;
+import com.amazonaws.auth.BasicAWSCredentials;
+import com.amazonaws.client.builder.AwsClientBuilder;
+import com.amazonaws.services.ec2.AmazonEC2;
+import com.amazonaws.services.ec2.AmazonEC2ClientBuilder;
+import com.amazonaws.services.ec2.model.DescribeInstancesRequest;
+import com.amazonaws.services.ec2.model.Filter;
+import java.util.concurrent.TimeUnit;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Fork;
+import org.openjdk.jmh.annotations.Level;
+import org.openjdk.jmh.annotations.Measurement;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.annotations.TearDown;
+import org.openjdk.jmh.annotations.Warmup;
+import org.openjdk.jmh.infra.Blackhole;
+
+/**
+ * V1 roundtrip benchmark for EC2 protocol using EC2 DescribeInstances via HTTP servlet.
+ */
+@State(Scope.Benchmark)
+@Warmup(iterations = 5)
+@Measurement(iterations = 5)
+@Fork(2)
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.MICROSECONDS)
+public class V1Ec2RoundtripBenchmark {
+
+ private ProtocolRoundtripServer server;
+ private AmazonEC2 client;
+ private DescribeInstancesRequest request;
+
+ @Setup(Level.Trial)
+ public void setup() throws Exception {
+ byte[] response = ProtocolRoundtripServer.loadFixture("ec2-protocol/describe-instances-response.xml");
+
+ ProtocolRoundtripServlet servlet = new ProtocolRoundtripServlet()
+ .defaultRoute("text/xml", response);
+
+ server = new ProtocolRoundtripServer(servlet);
+ server.start();
+
+ client = AmazonEC2ClientBuilder.standard()
+ .withEndpointConfiguration(new AwsClientBuilder.EndpointConfiguration(
+ server.getHttpUri().toString(), "us-east-1"))
+ .withCredentials(new AWSStaticCredentialsProvider(new BasicAWSCredentials("test", "test")))
+ .build();
+
+ request = new DescribeInstancesRequest()
+ .withInstanceIds("i-0abcdef1234567890")
+ .withFilters(
+ new Filter("instance-state-name").withValues("running"),
+ new Filter("instance-type").withValues("m5.xlarge"))
+ .withMaxResults(100);
+ }
+
+ @TearDown(Level.Trial)
+ public void tearDown() throws Exception {
+ client.shutdown();
+ server.stop();
+ }
+
+ @Benchmark
+ public void describeInstances(Blackhole bh) {
+ bh.consume(client.describeInstances(request));
+ }
+}
diff --git a/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V1JsonRoundtripBenchmark.java b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V1JsonRoundtripBenchmark.java
new file mode 100644
index 000000000000..d931402e15a0
--- /dev/null
+++ b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V1JsonRoundtripBenchmark.java
@@ -0,0 +1,114 @@
+/*
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License").
+ * You may not use this file except in compliance with the License.
+ * A copy of the License is located at
+ *
+ * http://aws.amazon.com/apache2.0
+ *
+ * or in the "license" file accompanying this file. This file is distributed
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+package software.amazon.awssdk.benchmark.apicall.protocol;
+
+import com.amazonaws.auth.AWSStaticCredentialsProvider;
+import com.amazonaws.auth.BasicAWSCredentials;
+import com.amazonaws.client.builder.AwsClientBuilder;
+import com.amazonaws.services.dynamodbv2.AmazonDynamoDB;
+import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClientBuilder;
+import com.amazonaws.services.dynamodbv2.model.AttributeValue;
+import com.amazonaws.services.dynamodbv2.model.PutItemRequest;
+import java.nio.ByteBuffer;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Fork;
+import org.openjdk.jmh.annotations.Level;
+import org.openjdk.jmh.annotations.Measurement;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.annotations.TearDown;
+import org.openjdk.jmh.annotations.Warmup;
+import org.openjdk.jmh.infra.Blackhole;
+
+/**
+ * V1 roundtrip benchmark for JSON protocol (aws-json) using DynamoDB PutItem via HTTP servlet.
+ */
+@State(Scope.Benchmark)
+@Warmup(iterations = 5)
+@Measurement(iterations = 5)
+@Fork(2)
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.MICROSECONDS)
+public class V1JsonRoundtripBenchmark {
+
+ private ProtocolRoundtripServer server;
+ private AmazonDynamoDB client;
+ private PutItemRequest putItemRequest;
+
+ @Setup(Level.Trial)
+ public void setup() throws Exception {
+ byte[] response = ProtocolRoundtripServer.loadFixture("json-protocol/putitem-response.json");
+
+ ProtocolRoundtripServlet servlet = new ProtocolRoundtripServlet()
+ .routeByTarget("DynamoDB_20120810.PutItem", "application/x-amz-json-1.0", response);
+
+ server = new ProtocolRoundtripServer(servlet);
+ server.start();
+
+ client = AmazonDynamoDBClientBuilder.standard()
+ .withEndpointConfiguration(new AwsClientBuilder.EndpointConfiguration(
+ server.getHttpUri().toString(), "us-east-1"))
+ .withCredentials(new AWSStaticCredentialsProvider(new BasicAWSCredentials("test", "test")))
+ .build();
+
+ putItemRequest = new PutItemRequest()
+ .withTableName("benchmark-table")
+ .withItem(itemMap());
+ }
+
+ @TearDown(Level.Trial)
+ public void tearDown() throws Exception {
+ client.shutdown();
+ server.stop();
+ }
+
+ @Benchmark
+ public void putItem(Blackhole bh) {
+ bh.consume(client.putItem(putItemRequest));
+ }
+
+ private static Map itemMap() {
+ Map item = new HashMap<>();
+ item.put("pk", new AttributeValue().withS("benchmark-key"));
+ item.put("sk", new AttributeValue().withN("100"));
+ item.put("stringField", new AttributeValue().withS("test-value"));
+ item.put("numberField", new AttributeValue().withN("123.456"));
+ item.put("binaryField", new AttributeValue().withB(ByteBuffer.wrap("hello world".getBytes())));
+ item.put("stringSetField", new AttributeValue().withSS("value1", "value2", "value3"));
+ item.put("numberSetField", new AttributeValue().withNS("1.1", "2.2", "3.3"));
+ item.put("boolField", new AttributeValue().withBOOL(false));
+ item.put("nullField", new AttributeValue().withNULL(true));
+ Map deep = new HashMap<>();
+ deep.put("level2", new AttributeValue().withN("999"));
+ Map nested = new HashMap<>();
+ nested.put("nested", new AttributeValue().withS("nested-value"));
+ nested.put("deepNested", new AttributeValue().withM(deep));
+ item.put("mapField", new AttributeValue().withM(nested));
+ item.put("listField", new AttributeValue().withL(
+ new AttributeValue().withS("item1"),
+ new AttributeValue().withN("42"),
+ new AttributeValue().withBOOL(true),
+ new AttributeValue().withNULL(true)));
+ return item;
+ }
+}
diff --git a/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V1QueryRoundtripBenchmark.java b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V1QueryRoundtripBenchmark.java
new file mode 100644
index 000000000000..9659bec30100
--- /dev/null
+++ b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V1QueryRoundtripBenchmark.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License").
+ * You may not use this file except in compliance with the License.
+ * A copy of the License is located at
+ *
+ * http://aws.amazon.com/apache2.0
+ *
+ * or in the "license" file accompanying this file. This file is distributed
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+package software.amazon.awssdk.benchmark.apicall.protocol;
+
+import com.amazonaws.auth.AWSStaticCredentialsProvider;
+import com.amazonaws.auth.BasicAWSCredentials;
+import com.amazonaws.client.builder.AwsClientBuilder;
+import com.amazonaws.services.securitytoken.AWSSecurityTokenService;
+import com.amazonaws.services.securitytoken.AWSSecurityTokenServiceClientBuilder;
+import com.amazonaws.services.securitytoken.model.AssumeRoleRequest;
+import java.util.concurrent.TimeUnit;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Fork;
+import org.openjdk.jmh.annotations.Level;
+import org.openjdk.jmh.annotations.Measurement;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.annotations.TearDown;
+import org.openjdk.jmh.annotations.Warmup;
+import org.openjdk.jmh.infra.Blackhole;
+
+/**
+ * V1 roundtrip benchmark for Query protocol using STS AssumeRole via HTTP servlet.
+ */
+@State(Scope.Benchmark)
+@Warmup(iterations = 5)
+@Measurement(iterations = 5)
+@Fork(2)
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.MICROSECONDS)
+public class V1QueryRoundtripBenchmark {
+
+ private ProtocolRoundtripServer server;
+ private AWSSecurityTokenService client;
+ private AssumeRoleRequest request;
+
+ @Setup(Level.Trial)
+ public void setup() throws Exception {
+ byte[] response = ProtocolRoundtripServer.loadFixture("query-protocol/assumerole-response.xml");
+
+ ProtocolRoundtripServlet servlet = new ProtocolRoundtripServlet()
+ .defaultRoute("text/xml", response);
+
+ server = new ProtocolRoundtripServer(servlet);
+ server.start();
+
+ client = AWSSecurityTokenServiceClientBuilder.standard()
+ .withEndpointConfiguration(new AwsClientBuilder.EndpointConfiguration(
+ server.getHttpUri().toString(), "us-east-1"))
+ .withCredentials(new AWSStaticCredentialsProvider(new BasicAWSCredentials("test", "test")))
+ .build();
+
+ request = new AssumeRoleRequest()
+ .withRoleArn("arn:aws:iam::123456789012:role/benchmark-role")
+ .withRoleSessionName("benchmark-session")
+ .withDurationSeconds(3600)
+ .withExternalId("benchmark-external-id")
+ .withPolicy("{\"Version\":\"2012-10-17\"}");
+ }
+
+ @TearDown(Level.Trial)
+ public void tearDown() throws Exception {
+ client.shutdown();
+ server.stop();
+ }
+
+ @Benchmark
+ public void assumeRole(Blackhole bh) {
+ bh.consume(client.assumeRole(request));
+ }
+}
diff --git a/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V1RestJsonRoundtripBenchmark.java b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V1RestJsonRoundtripBenchmark.java
new file mode 100644
index 000000000000..4283ac55a885
--- /dev/null
+++ b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V1RestJsonRoundtripBenchmark.java
@@ -0,0 +1,106 @@
+/*
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License").
+ * You may not use this file except in compliance with the License.
+ * A copy of the License is located at
+ *
+ * http://aws.amazon.com/apache2.0
+ *
+ * or in the "license" file accompanying this file. This file is distributed
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+package software.amazon.awssdk.benchmark.apicall.protocol;
+
+import com.amazonaws.auth.AWSStaticCredentialsProvider;
+import com.amazonaws.auth.BasicAWSCredentials;
+import com.amazonaws.client.builder.AwsClientBuilder;
+import com.amazonaws.services.lambda.AWSLambda;
+import com.amazonaws.services.lambda.AWSLambdaClientBuilder;
+import com.amazonaws.services.lambda.model.CreateFunctionRequest;
+import com.amazonaws.services.lambda.model.Environment;
+import com.amazonaws.services.lambda.model.FunctionCode;
+import com.amazonaws.services.lambda.model.Runtime;
+import com.amazonaws.services.lambda.model.TracingConfig;
+import com.amazonaws.services.lambda.model.TracingMode;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Fork;
+import org.openjdk.jmh.annotations.Level;
+import org.openjdk.jmh.annotations.Measurement;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.annotations.TearDown;
+import org.openjdk.jmh.annotations.Warmup;
+import org.openjdk.jmh.infra.Blackhole;
+
+/**
+ * V1 roundtrip benchmark for REST-JSON protocol using Lambda CreateFunction via HTTP servlet.
+ */
+@State(Scope.Benchmark)
+@Warmup(iterations = 5)
+@Measurement(iterations = 5)
+@Fork(2)
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.MICROSECONDS)
+public class V1RestJsonRoundtripBenchmark {
+
+ private ProtocolRoundtripServer server;
+ private AWSLambda client;
+ private CreateFunctionRequest request;
+
+ @Setup(Level.Trial)
+ public void setup() throws Exception {
+ byte[] response = ProtocolRoundtripServer.loadFixture("rest-json-protocol/createfunction-response.json");
+
+ ProtocolRoundtripServlet servlet = new ProtocolRoundtripServlet()
+ .routeByUri("/2015-03-31/functions", "application/json", response);
+
+ server = new ProtocolRoundtripServer(servlet);
+ server.start();
+
+ client = AWSLambdaClientBuilder.standard()
+ .withEndpointConfiguration(new AwsClientBuilder.EndpointConfiguration(
+ server.getHttpUri().toString(), "us-east-1"))
+ .withCredentials(new AWSStaticCredentialsProvider(new BasicAWSCredentials("test", "test")))
+ .build();
+
+ Map envVars = new HashMap<>();
+ envVars.put("ENV_VAR_1", "value1");
+
+ request = new CreateFunctionRequest()
+ .withFunctionName("benchmark-function")
+ .withRuntime(Runtime.Java8)
+ .withRole("arn:aws:iam::123456789012:role/lambda-role")
+ .withHandler("com.example.Handler::handleRequest")
+ .withCode(new FunctionCode()
+ .withS3Bucket("my-deploy-bucket")
+ .withS3Key("code/function.zip"))
+ .withDescription("Benchmark test function")
+ .withTimeout(30)
+ .withMemorySize(512)
+ .withPublish(false)
+ .withEnvironment(new Environment().withVariables(envVars))
+ .withTracingConfig(new TracingConfig().withMode(TracingMode.Active));
+ }
+
+ @TearDown(Level.Trial)
+ public void tearDown() throws Exception {
+ client.shutdown();
+ server.stop();
+ }
+
+ @Benchmark
+ public void createFunction(Blackhole bh) {
+ bh.consume(client.createFunction(request));
+ }
+}
diff --git a/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V1RestXmlRoundtripBenchmark.java b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V1RestXmlRoundtripBenchmark.java
new file mode 100644
index 000000000000..ac9968862e0a
--- /dev/null
+++ b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V1RestXmlRoundtripBenchmark.java
@@ -0,0 +1,120 @@
+/*
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License").
+ * You may not use this file except in compliance with the License.
+ * A copy of the License is located at
+ *
+ * http://aws.amazon.com/apache2.0
+ *
+ * or in the "license" file accompanying this file. This file is distributed
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+package software.amazon.awssdk.benchmark.apicall.protocol;
+
+import com.amazonaws.auth.AWSStaticCredentialsProvider;
+import com.amazonaws.auth.BasicAWSCredentials;
+import com.amazonaws.client.builder.AwsClientBuilder;
+import com.amazonaws.services.cloudfront.AmazonCloudFront;
+import com.amazonaws.services.cloudfront.AmazonCloudFrontClientBuilder;
+import com.amazonaws.services.cloudfront.model.Aliases;
+import com.amazonaws.services.cloudfront.model.AllowedMethods;
+import com.amazonaws.services.cloudfront.model.CachedMethods;
+import com.amazonaws.services.cloudfront.model.CreateDistributionRequest;
+import com.amazonaws.services.cloudfront.model.DefaultCacheBehavior;
+import com.amazonaws.services.cloudfront.model.DistributionConfig;
+import com.amazonaws.services.cloudfront.model.Method;
+import com.amazonaws.services.cloudfront.model.Origin;
+import com.amazonaws.services.cloudfront.model.Origins;
+import com.amazonaws.services.cloudfront.model.S3OriginConfig;
+import com.amazonaws.services.cloudfront.model.ViewerProtocolPolicy;
+import java.util.Collections;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Fork;
+import org.openjdk.jmh.annotations.Level;
+import org.openjdk.jmh.annotations.Measurement;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.annotations.TearDown;
+import org.openjdk.jmh.annotations.Warmup;
+import org.openjdk.jmh.infra.Blackhole;
+
+/**
+ * V1 roundtrip benchmark for REST-XML protocol using CloudFront CreateDistribution via HTTP servlet.
+ */
+@State(Scope.Benchmark)
+@Warmup(iterations = 5)
+@Measurement(iterations = 5)
+@Fork(2)
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.MICROSECONDS)
+public class V1RestXmlRoundtripBenchmark {
+
+ private ProtocolRoundtripServer server;
+ private AmazonCloudFront client;
+ private CreateDistributionRequest request;
+
+ @Setup(Level.Trial)
+ public void setup() throws Exception {
+ byte[] response = ProtocolRoundtripServer.loadFixture("rest-xml-protocol/create-distribution-response.xml");
+
+ Map headers = Collections.singletonMap("ETag", "E2QWRUHEXAMPLE");
+ ProtocolRoundtripServlet servlet = new ProtocolRoundtripServlet()
+ .routeByUri("/2020-05-31/distribution", "application/xml", response, headers);
+
+ server = new ProtocolRoundtripServer(servlet);
+ server.start();
+
+ client = AmazonCloudFrontClientBuilder.standard()
+ .withEndpointConfiguration(new AwsClientBuilder.EndpointConfiguration(
+ server.getHttpUri().toString(), "us-east-1"))
+ .withCredentials(new AWSStaticCredentialsProvider(new BasicAWSCredentials("test", "test")))
+ .build();
+
+ request = new CreateDistributionRequest()
+ .withDistributionConfig(new DistributionConfig()
+ .withCallerReference("benchmark-ref-2024")
+ .withAliases(new Aliases()
+ .withQuantity(2)
+ .withItems("www.example.com", "cdn.example.com"))
+ .withDefaultRootObject("index.html")
+ .withOrigins(new Origins()
+ .withQuantity(1)
+ .withItems(new Origin()
+ .withId("myS3Origin")
+ .withDomainName("mybucket.s3.amazonaws.com")
+ .withOriginPath("/production")
+ .withS3OriginConfig(new S3OriginConfig()
+ .withOriginAccessIdentity("origin-access-identity/cloudfront/E127EXAMPLE51Z"))))
+ .withDefaultCacheBehavior(new DefaultCacheBehavior()
+ .withTargetOriginId("myS3Origin")
+ .withViewerProtocolPolicy(ViewerProtocolPolicy.RedirectToHttps)
+ .withAllowedMethods(new AllowedMethods()
+ .withQuantity(3)
+ .withItems(Method.GET, Method.HEAD, Method.OPTIONS)
+ .withCachedMethods(new CachedMethods()
+ .withQuantity(2)
+ .withItems(Method.GET, Method.HEAD)))
+ .withCompress(true)));
+ }
+
+ @TearDown(Level.Trial)
+ public void tearDown() throws Exception {
+ client.shutdown();
+ server.stop();
+ }
+
+ @Benchmark
+ public void createDistribution(Blackhole bh) {
+ bh.consume(client.createDistribution(request));
+ }
+}
diff --git a/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V2CborRoundtripBenchmark.java b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V2CborRoundtripBenchmark.java
new file mode 100644
index 000000000000..13c92fc7a771
--- /dev/null
+++ b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V2CborRoundtripBenchmark.java
@@ -0,0 +1,147 @@
+/*
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License").
+ * You may not use this file except in compliance with the License.
+ * A copy of the License is located at
+ *
+ * http://aws.amazon.com/apache2.0
+ *
+ * or in the "license" file accompanying this file. This file is distributed
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+package software.amazon.awssdk.benchmark.apicall.protocol;
+
+import java.time.Instant;
+import java.util.concurrent.TimeUnit;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Fork;
+import org.openjdk.jmh.annotations.Level;
+import org.openjdk.jmh.annotations.Measurement;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.annotations.TearDown;
+import org.openjdk.jmh.annotations.Warmup;
+import org.openjdk.jmh.infra.Blackhole;
+import software.amazon.awssdk.auth.credentials.AwsBasicCredentials;
+import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider;
+import software.amazon.awssdk.http.apache5.Apache5HttpClient;
+import software.amazon.awssdk.protocols.json.StructuredJsonGenerator;
+import software.amazon.awssdk.protocols.rpcv2.internal.SdkStructuredRpcV2CborFactory;
+import software.amazon.awssdk.regions.Region;
+import software.amazon.awssdk.services.cloudwatch.CloudWatchClient;
+import software.amazon.awssdk.services.cloudwatch.model.GetMetricDataRequest;
+import software.amazon.awssdk.services.cloudwatch.model.Metric;
+import software.amazon.awssdk.services.cloudwatch.model.MetricDataQuery;
+import software.amazon.awssdk.services.cloudwatch.model.MetricStat;
+
+/**
+ * Roundtrip benchmark for SmithyRpcV2 CBOR protocol using CloudWatch GetMetricData via HTTP servlet.
+ */
+@State(Scope.Benchmark)
+@Warmup(iterations = 5)
+@Measurement(iterations = 5)
+@Fork(2)
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.MICROSECONDS)
+public class V2CborRoundtripBenchmark {
+
+ private ProtocolRoundtripServer server;
+ private CloudWatchClient client;
+ private GetMetricDataRequest request;
+
+ @Setup(Level.Trial)
+ public void setup() throws Exception {
+ byte[] response = createCborResponseFixture();
+
+ ProtocolRoundtripServlet servlet = new ProtocolRoundtripServlet()
+ .defaultRoute("application/cbor", response);
+
+ server = new ProtocolRoundtripServer(servlet);
+ server.start();
+
+ client = CloudWatchClient.builder()
+ .endpointOverride(server.getHttpUri())
+ .region(Region.US_EAST_1)
+ .credentialsProvider(StaticCredentialsProvider.create(AwsBasicCredentials.create("test", "test")))
+ .httpClient(Apache5HttpClient.create())
+ .build();
+
+ Instant end = Instant.parse("2026-03-09T00:00:00Z");
+ Instant start = end.minusSeconds(3600);
+ request = GetMetricDataRequest.builder()
+ .startTime(start)
+ .endTime(end)
+ .maxDatapoints(1000)
+ .metricDataQueries(
+ MetricDataQuery.builder()
+ .id("cpu")
+ .metricStat(MetricStat.builder()
+ .metric(Metric.builder()
+ .namespace("AWS/EC2")
+ .metricName("CPUUtilization")
+ .build())
+ .period(300)
+ .stat("Average")
+ .build())
+ .returnData(true)
+ .build())
+ .build();
+ }
+
+ @TearDown(Level.Trial)
+ public void tearDown() throws Exception {
+ client.close();
+ server.stop();
+ }
+
+ @Benchmark
+ public void getMetricData(Blackhole bh) {
+ bh.consume(client.getMetricData(request));
+ }
+
+ private static byte[] createCborResponseFixture() {
+ StructuredJsonGenerator gen =
+ SdkStructuredRpcV2CborFactory.SDK_CBOR_FACTORY.createWriter("application/cbor");
+ gen.writeStartObject();
+ gen.writeFieldName("MetricDataResults");
+ gen.writeStartArray();
+ gen.writeStartObject();
+ gen.writeFieldName("Id");
+ gen.writeValue("cpu");
+ gen.writeFieldName("Label");
+ gen.writeValue("CPUUtilization");
+ gen.writeFieldName("StatusCode");
+ gen.writeValue("Complete");
+ gen.writeFieldName("Timestamps");
+ gen.writeStartArray();
+ long base = 1772611200L;
+ for (int i = 0; i < 12; i++) {
+ gen.writeValue((double) ((base + i * 300) * 1000));
+ }
+ gen.writeEndArray();
+ gen.writeFieldName("Values");
+ gen.writeStartArray();
+ for (int i = 0; i < 12; i++) {
+ gen.writeValue(45.2 + i * 1.1);
+ }
+ gen.writeEndArray();
+ gen.writeFieldName("Messages");
+ gen.writeStartArray();
+ gen.writeEndArray();
+ gen.writeEndObject();
+ gen.writeEndArray();
+ gen.writeFieldName("Messages");
+ gen.writeStartArray();
+ gen.writeEndArray();
+ gen.writeEndObject();
+ return gen.getBytes();
+ }
+}
diff --git a/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V2Ec2RoundtripBenchmark.java b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V2Ec2RoundtripBenchmark.java
new file mode 100644
index 000000000000..c52077bcadf3
--- /dev/null
+++ b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V2Ec2RoundtripBenchmark.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License").
+ * You may not use this file except in compliance with the License.
+ * A copy of the License is located at
+ *
+ * http://aws.amazon.com/apache2.0
+ *
+ * or in the "license" file accompanying this file. This file is distributed
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+package software.amazon.awssdk.benchmark.apicall.protocol;
+
+import java.util.concurrent.TimeUnit;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Fork;
+import org.openjdk.jmh.annotations.Level;
+import org.openjdk.jmh.annotations.Measurement;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.annotations.TearDown;
+import org.openjdk.jmh.annotations.Warmup;
+import org.openjdk.jmh.infra.Blackhole;
+import software.amazon.awssdk.auth.credentials.AwsBasicCredentials;
+import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider;
+import software.amazon.awssdk.http.apache5.Apache5HttpClient;
+import software.amazon.awssdk.regions.Region;
+import software.amazon.awssdk.services.ec2.Ec2Client;
+import software.amazon.awssdk.services.ec2.model.DescribeInstancesRequest;
+import software.amazon.awssdk.services.ec2.model.Filter;
+
+/**
+ * Roundtrip benchmark for EC2 protocol using EC2 DescribeInstances via HTTP servlet.
+ */
+@State(Scope.Benchmark)
+@Warmup(iterations = 5)
+@Measurement(iterations = 5)
+@Fork(2)
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.MICROSECONDS)
+public class V2Ec2RoundtripBenchmark {
+
+ private ProtocolRoundtripServer server;
+ private Ec2Client client;
+ private DescribeInstancesRequest request;
+
+ @Setup(Level.Trial)
+ public void setup() throws Exception {
+ byte[] response = ProtocolRoundtripServer.loadFixture("ec2-protocol/describe-instances-response.xml");
+
+ ProtocolRoundtripServlet servlet = new ProtocolRoundtripServlet()
+ .defaultRoute("text/xml", response);
+
+ server = new ProtocolRoundtripServer(servlet);
+ server.start();
+
+ client = Ec2Client.builder()
+ .endpointOverride(server.getHttpUri())
+ .region(Region.US_EAST_1)
+ .credentialsProvider(StaticCredentialsProvider.create(AwsBasicCredentials.create("test", "test")))
+ .httpClient(Apache5HttpClient.create())
+ .build();
+
+ request = DescribeInstancesRequest.builder()
+ .instanceIds("i-0abcdef1234567890")
+ .filters(
+ Filter.builder().name("instance-state-name").values("running").build(),
+ Filter.builder().name("instance-type").values("m5.xlarge").build())
+ .maxResults(100)
+ .build();
+ }
+
+ @TearDown(Level.Trial)
+ public void tearDown() throws Exception {
+ client.close();
+ server.stop();
+ }
+
+ @Benchmark
+ public void describeInstances(Blackhole bh) {
+ bh.consume(client.describeInstances(request));
+ }
+}
diff --git a/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V2JsonRoundtripBenchmark.java b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V2JsonRoundtripBenchmark.java
new file mode 100644
index 000000000000..2c6453e9b79a
--- /dev/null
+++ b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V2JsonRoundtripBenchmark.java
@@ -0,0 +1,116 @@
+/*
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License").
+ * You may not use this file except in compliance with the License.
+ * A copy of the License is located at
+ *
+ * http://aws.amazon.com/apache2.0
+ *
+ * or in the "license" file accompanying this file. This file is distributed
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+package software.amazon.awssdk.benchmark.apicall.protocol;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Fork;
+import org.openjdk.jmh.annotations.Level;
+import org.openjdk.jmh.annotations.Measurement;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.annotations.TearDown;
+import org.openjdk.jmh.annotations.Warmup;
+import org.openjdk.jmh.infra.Blackhole;
+import software.amazon.awssdk.auth.credentials.AwsBasicCredentials;
+import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider;
+import software.amazon.awssdk.core.SdkBytes;
+import software.amazon.awssdk.http.apache5.Apache5HttpClient;
+import software.amazon.awssdk.regions.Region;
+import software.amazon.awssdk.services.dynamodb.DynamoDbClient;
+import software.amazon.awssdk.services.dynamodb.model.AttributeValue;
+import software.amazon.awssdk.services.dynamodb.model.PutItemRequest;
+
+/**
+ * Roundtrip benchmark for JSON protocol (aws-json) using DynamoDB PutItem via HTTP servlet.
+ */
+@State(Scope.Benchmark)
+@Warmup(iterations = 5)
+@Measurement(iterations = 5)
+@Fork(2)
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.MICROSECONDS)
+public class V2JsonRoundtripBenchmark {
+
+ private ProtocolRoundtripServer server;
+ private DynamoDbClient client;
+ private PutItemRequest putItemRequest;
+
+ @Setup(Level.Trial)
+ public void setup() throws Exception {
+ byte[] response = ProtocolRoundtripServer.loadFixture("json-protocol/putitem-response.json");
+
+ ProtocolRoundtripServlet servlet = new ProtocolRoundtripServlet()
+ .routeByTarget("DynamoDB_20120810.PutItem", "application/x-amz-json-1.0", response);
+
+ server = new ProtocolRoundtripServer(servlet);
+ server.start();
+
+ client = DynamoDbClient.builder()
+ .endpointOverride(server.getHttpUri())
+ .region(Region.US_EAST_1)
+ .credentialsProvider(StaticCredentialsProvider.create(AwsBasicCredentials.create("test", "test")))
+ .httpClient(Apache5HttpClient.create())
+ .build();
+
+ putItemRequest = PutItemRequest.builder()
+ .tableName("benchmark-table")
+ .item(itemMap())
+ .build();
+ }
+
+ @TearDown(Level.Trial)
+ public void tearDown() throws Exception {
+ client.close();
+ server.stop();
+ }
+
+ @Benchmark
+ public void putItem(Blackhole bh) {
+ bh.consume(client.putItem(putItemRequest));
+ }
+
+ private static Map itemMap() {
+ Map item = new HashMap<>();
+ item.put("pk", AttributeValue.fromS("benchmark-key"));
+ item.put("sk", AttributeValue.fromN("100"));
+ item.put("stringField", AttributeValue.fromS("test-value"));
+ item.put("numberField", AttributeValue.fromN("123.456"));
+ item.put("binaryField", AttributeValue.fromB(SdkBytes.fromUtf8String("hello world")));
+ item.put("stringSetField", AttributeValue.builder().ss("value1", "value2", "value3").build());
+ item.put("numberSetField", AttributeValue.builder().ns("1.1", "2.2", "3.3").build());
+ item.put("boolField", AttributeValue.fromBool(false));
+ item.put("nullField", AttributeValue.builder().nul(true).build());
+ Map deep = new HashMap<>();
+ deep.put("level2", AttributeValue.fromN("999"));
+ Map nested = new HashMap<>();
+ nested.put("nested", AttributeValue.fromS("nested-value"));
+ nested.put("deepNested", AttributeValue.fromM(deep));
+ item.put("mapField", AttributeValue.fromM(nested));
+ item.put("listField", AttributeValue.builder().l(
+ AttributeValue.fromS("item1"),
+ AttributeValue.fromN("42"),
+ AttributeValue.fromBool(true),
+ AttributeValue.builder().nul(true).build()).build());
+ return item;
+ }
+}
diff --git a/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V2QueryRoundtripBenchmark.java b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V2QueryRoundtripBenchmark.java
new file mode 100644
index 000000000000..a1bbcbcc1b79
--- /dev/null
+++ b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V2QueryRoundtripBenchmark.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License").
+ * You may not use this file except in compliance with the License.
+ * A copy of the License is located at
+ *
+ * http://aws.amazon.com/apache2.0
+ *
+ * or in the "license" file accompanying this file. This file is distributed
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+package software.amazon.awssdk.benchmark.apicall.protocol;
+
+import java.util.concurrent.TimeUnit;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Fork;
+import org.openjdk.jmh.annotations.Level;
+import org.openjdk.jmh.annotations.Measurement;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.annotations.TearDown;
+import org.openjdk.jmh.annotations.Warmup;
+import org.openjdk.jmh.infra.Blackhole;
+import software.amazon.awssdk.auth.credentials.AwsBasicCredentials;
+import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider;
+import software.amazon.awssdk.http.apache5.Apache5HttpClient;
+import software.amazon.awssdk.regions.Region;
+import software.amazon.awssdk.services.sts.StsClient;
+import software.amazon.awssdk.services.sts.model.AssumeRoleRequest;
+
+/**
+ * Roundtrip benchmark for Query protocol using STS AssumeRole via HTTP servlet.
+ */
+@State(Scope.Benchmark)
+@Warmup(iterations = 5)
+@Measurement(iterations = 5)
+@Fork(2)
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.MICROSECONDS)
+public class V2QueryRoundtripBenchmark {
+
+ private ProtocolRoundtripServer server;
+ private StsClient client;
+ private AssumeRoleRequest request;
+
+ @Setup(Level.Trial)
+ public void setup() throws Exception {
+ byte[] response = ProtocolRoundtripServer.loadFixture("query-protocol/assumerole-response.xml");
+
+ ProtocolRoundtripServlet servlet = new ProtocolRoundtripServlet()
+ .defaultRoute("text/xml", response);
+
+ server = new ProtocolRoundtripServer(servlet);
+ server.start();
+
+ client = StsClient.builder()
+ .endpointOverride(server.getHttpUri())
+ .region(Region.US_EAST_1)
+ .credentialsProvider(StaticCredentialsProvider.create(AwsBasicCredentials.create("test", "test")))
+ .httpClient(Apache5HttpClient.create())
+ .build();
+
+ request = AssumeRoleRequest.builder()
+ .roleArn("arn:aws:iam::123456789012:role/benchmark-role")
+ .roleSessionName("benchmark-session")
+ .durationSeconds(3600)
+ .externalId("benchmark-external-id")
+ .policy("{\"Version\":\"2012-10-17\"}")
+ .build();
+ }
+
+ @TearDown(Level.Trial)
+ public void tearDown() throws Exception {
+ client.close();
+ server.stop();
+ }
+
+ @Benchmark
+ public void assumeRole(Blackhole bh) {
+ bh.consume(client.assumeRole(request));
+ }
+}
diff --git a/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V2RestJsonRoundtripBenchmark.java b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V2RestJsonRoundtripBenchmark.java
new file mode 100644
index 000000000000..f5dbfab3b38b
--- /dev/null
+++ b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V2RestJsonRoundtripBenchmark.java
@@ -0,0 +1,109 @@
+/*
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License").
+ * You may not use this file except in compliance with the License.
+ * A copy of the License is located at
+ *
+ * http://aws.amazon.com/apache2.0
+ *
+ * or in the "license" file accompanying this file. This file is distributed
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+package software.amazon.awssdk.benchmark.apicall.protocol;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Fork;
+import org.openjdk.jmh.annotations.Level;
+import org.openjdk.jmh.annotations.Measurement;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.annotations.TearDown;
+import org.openjdk.jmh.annotations.Warmup;
+import org.openjdk.jmh.infra.Blackhole;
+import software.amazon.awssdk.auth.credentials.AwsBasicCredentials;
+import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider;
+import software.amazon.awssdk.http.apache5.Apache5HttpClient;
+import software.amazon.awssdk.regions.Region;
+import software.amazon.awssdk.services.lambda.LambdaClient;
+import software.amazon.awssdk.services.lambda.model.CreateFunctionRequest;
+import software.amazon.awssdk.services.lambda.model.Environment;
+import software.amazon.awssdk.services.lambda.model.FunctionCode;
+import software.amazon.awssdk.services.lambda.model.Runtime;
+import software.amazon.awssdk.services.lambda.model.TracingConfig;
+import software.amazon.awssdk.services.lambda.model.TracingMode;
+
+/**
+ * Roundtrip benchmark for REST-JSON protocol using Lambda CreateFunction via HTTP servlet.
+ */
+@State(Scope.Benchmark)
+@Warmup(iterations = 5)
+@Measurement(iterations = 5)
+@Fork(2)
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.MICROSECONDS)
+public class V2RestJsonRoundtripBenchmark {
+
+ private ProtocolRoundtripServer server;
+ private LambdaClient client;
+ private CreateFunctionRequest request;
+
+ @Setup(Level.Trial)
+ public void setup() throws Exception {
+ byte[] response = ProtocolRoundtripServer.loadFixture("rest-json-protocol/createfunction-response.json");
+
+ ProtocolRoundtripServlet servlet = new ProtocolRoundtripServlet()
+ .routeByUri("/2015-03-31/functions", "application/json", response);
+
+ server = new ProtocolRoundtripServer(servlet);
+ server.start();
+
+ client = LambdaClient.builder()
+ .endpointOverride(server.getHttpUri())
+ .region(Region.US_EAST_1)
+ .credentialsProvider(StaticCredentialsProvider.create(AwsBasicCredentials.create("test", "test")))
+ .httpClient(Apache5HttpClient.create())
+ .build();
+
+ Map envVars = new HashMap<>();
+ envVars.put("ENV_VAR_1", "value1");
+
+ request = CreateFunctionRequest.builder()
+ .functionName("benchmark-function")
+ .runtime(Runtime.JAVA8)
+ .role("arn:aws:iam::123456789012:role/lambda-role")
+ .handler("com.example.Handler::handleRequest")
+ .code(FunctionCode.builder()
+ .s3Bucket("my-deploy-bucket")
+ .s3Key("code/function.zip")
+ .build())
+ .description("Benchmark test function")
+ .timeout(30)
+ .memorySize(512)
+ .publish(false)
+ .environment(Environment.builder().variables(envVars).build())
+ .tracingConfig(TracingConfig.builder().mode(TracingMode.ACTIVE).build())
+ .build();
+ }
+
+ @TearDown(Level.Trial)
+ public void tearDown() throws Exception {
+ client.close();
+ server.stop();
+ }
+
+ @Benchmark
+ public void createFunction(Blackhole bh) {
+ bh.consume(client.createFunction(request));
+ }
+}
diff --git a/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V2RestXmlRoundtripBenchmark.java b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V2RestXmlRoundtripBenchmark.java
new file mode 100644
index 000000000000..eee8fb19e3dc
--- /dev/null
+++ b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V2RestXmlRoundtripBenchmark.java
@@ -0,0 +1,130 @@
+/*
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License").
+ * You may not use this file except in compliance with the License.
+ * A copy of the License is located at
+ *
+ * http://aws.amazon.com/apache2.0
+ *
+ * or in the "license" file accompanying this file. This file is distributed
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+package software.amazon.awssdk.benchmark.apicall.protocol;
+
+import java.util.Collections;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Fork;
+import org.openjdk.jmh.annotations.Level;
+import org.openjdk.jmh.annotations.Measurement;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.annotations.TearDown;
+import org.openjdk.jmh.annotations.Warmup;
+import org.openjdk.jmh.infra.Blackhole;
+import software.amazon.awssdk.auth.credentials.AwsBasicCredentials;
+import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider;
+import software.amazon.awssdk.http.apache5.Apache5HttpClient;
+import software.amazon.awssdk.regions.Region;
+import software.amazon.awssdk.services.cloudfront.CloudFrontClient;
+import software.amazon.awssdk.services.cloudfront.model.Aliases;
+import software.amazon.awssdk.services.cloudfront.model.AllowedMethods;
+import software.amazon.awssdk.services.cloudfront.model.CachedMethods;
+import software.amazon.awssdk.services.cloudfront.model.CreateDistributionRequest;
+import software.amazon.awssdk.services.cloudfront.model.DefaultCacheBehavior;
+import software.amazon.awssdk.services.cloudfront.model.DistributionConfig;
+import software.amazon.awssdk.services.cloudfront.model.Method;
+import software.amazon.awssdk.services.cloudfront.model.Origin;
+import software.amazon.awssdk.services.cloudfront.model.Origins;
+import software.amazon.awssdk.services.cloudfront.model.S3OriginConfig;
+import software.amazon.awssdk.services.cloudfront.model.ViewerProtocolPolicy;
+
+/**
+ * Roundtrip benchmark for REST-XML protocol using CloudFront CreateDistribution via HTTP servlet.
+ */
+@State(Scope.Benchmark)
+@Warmup(iterations = 5)
+@Measurement(iterations = 5)
+@Fork(2)
+@BenchmarkMode(Mode.Throughput)
+@OutputTimeUnit(TimeUnit.MICROSECONDS)
+public class V2RestXmlRoundtripBenchmark {
+
+ private ProtocolRoundtripServer server;
+ private CloudFrontClient client;
+ private CreateDistributionRequest request;
+
+ @Setup(Level.Trial)
+ public void setup() throws Exception {
+ byte[] response = ProtocolRoundtripServer.loadFixture("rest-xml-protocol/create-distribution-response.xml");
+
+ Map headers = Collections.singletonMap("ETag", "E2QWRUHEXAMPLE");
+ ProtocolRoundtripServlet servlet = new ProtocolRoundtripServlet()
+ .routeByUri("/2020-05-31/distribution", "application/xml", response, headers);
+
+ server = new ProtocolRoundtripServer(servlet);
+ server.start();
+
+ client = CloudFrontClient.builder()
+ .endpointOverride(server.getHttpUri())
+ .region(Region.US_EAST_1)
+ .credentialsProvider(StaticCredentialsProvider.create(AwsBasicCredentials.create("test", "test")))
+ .httpClient(Apache5HttpClient.create())
+ .build();
+
+ request = CreateDistributionRequest.builder()
+ .distributionConfig(DistributionConfig.builder()
+ .callerReference("benchmark-ref-2024")
+ .aliases(Aliases.builder()
+ .quantity(2)
+ .items("www.example.com", "cdn.example.com")
+ .build())
+ .defaultRootObject("index.html")
+ .origins(Origins.builder()
+ .quantity(1)
+ .items(Origin.builder()
+ .id("myS3Origin")
+ .domainName("mybucket.s3.amazonaws.com")
+ .originPath("/production")
+ .s3OriginConfig(S3OriginConfig.builder()
+ .originAccessIdentity("origin-access-identity/cloudfront/E127EXAMPLE51Z")
+ .build())
+ .build())
+ .build())
+ .defaultCacheBehavior(DefaultCacheBehavior.builder()
+ .targetOriginId("myS3Origin")
+ .viewerProtocolPolicy(ViewerProtocolPolicy.REDIRECT_TO_HTTPS)
+ .allowedMethods(AllowedMethods.builder()
+ .quantity(3)
+ .items(Method.GET, Method.HEAD, Method.OPTIONS)
+ .cachedMethods(CachedMethods.builder()
+ .quantity(2)
+ .items(Method.GET, Method.HEAD)
+ .build())
+ .build())
+ .compress(true)
+ .build())
+ .build())
+ .build();
+ }
+
+ @TearDown(Level.Trial)
+ public void tearDown() throws Exception {
+ client.close();
+ server.stop();
+ }
+
+ @Benchmark
+ public void createDistribution(Blackhole bh) {
+ bh.consume(client.createDistribution(request));
+ }
+}
From 29cdadb83eb53ab5c0deee2eb132ca07d348e577 Mon Sep 17 00:00:00 2001
From: RanVaknin <50976344+RanVaknin@users.noreply.github.com>
Date: Tue, 17 Mar 2026 09:53:10 -0700
Subject: [PATCH 5/7] Change timeunit to seconds
---
.../benchmark/apicall/protocol/V1CborRoundtripBenchmark.java | 2 +-
.../benchmark/apicall/protocol/V1Ec2RoundtripBenchmark.java | 2 +-
.../benchmark/apicall/protocol/V1JsonRoundtripBenchmark.java | 2 +-
.../benchmark/apicall/protocol/V1QueryRoundtripBenchmark.java | 2 +-
.../apicall/protocol/V1RestJsonRoundtripBenchmark.java | 2 +-
.../benchmark/apicall/protocol/V1RestXmlRoundtripBenchmark.java | 2 +-
.../benchmark/apicall/protocol/V2CborRoundtripBenchmark.java | 2 +-
.../benchmark/apicall/protocol/V2Ec2RoundtripBenchmark.java | 2 +-
.../benchmark/apicall/protocol/V2JsonRoundtripBenchmark.java | 2 +-
.../benchmark/apicall/protocol/V2QueryRoundtripBenchmark.java | 2 +-
.../apicall/protocol/V2RestJsonRoundtripBenchmark.java | 2 +-
.../benchmark/apicall/protocol/V2RestXmlRoundtripBenchmark.java | 2 +-
12 files changed, 12 insertions(+), 12 deletions(-)
diff --git a/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V1CborRoundtripBenchmark.java b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V1CborRoundtripBenchmark.java
index 1e2e369e1e49..402bec59dc1c 100644
--- a/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V1CborRoundtripBenchmark.java
+++ b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V1CborRoundtripBenchmark.java
@@ -50,7 +50,7 @@
@Measurement(iterations = 5)
@Fork(2)
@BenchmarkMode(Mode.Throughput)
-@OutputTimeUnit(TimeUnit.MICROSECONDS)
+@OutputTimeUnit(TimeUnit.SECONDS)
public class V1CborRoundtripBenchmark {
private ProtocolRoundtripServer server;
diff --git a/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V1Ec2RoundtripBenchmark.java b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V1Ec2RoundtripBenchmark.java
index ebe47b85a100..aab3116f4a29 100644
--- a/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V1Ec2RoundtripBenchmark.java
+++ b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V1Ec2RoundtripBenchmark.java
@@ -45,7 +45,7 @@
@Measurement(iterations = 5)
@Fork(2)
@BenchmarkMode(Mode.Throughput)
-@OutputTimeUnit(TimeUnit.MICROSECONDS)
+@OutputTimeUnit(TimeUnit.SECONDS)
public class V1Ec2RoundtripBenchmark {
private ProtocolRoundtripServer server;
diff --git a/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V1JsonRoundtripBenchmark.java b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V1JsonRoundtripBenchmark.java
index d931402e15a0..0e345a761c3d 100644
--- a/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V1JsonRoundtripBenchmark.java
+++ b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V1JsonRoundtripBenchmark.java
@@ -48,7 +48,7 @@
@Measurement(iterations = 5)
@Fork(2)
@BenchmarkMode(Mode.Throughput)
-@OutputTimeUnit(TimeUnit.MICROSECONDS)
+@OutputTimeUnit(TimeUnit.SECONDS)
public class V1JsonRoundtripBenchmark {
private ProtocolRoundtripServer server;
diff --git a/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V1QueryRoundtripBenchmark.java b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V1QueryRoundtripBenchmark.java
index 9659bec30100..cf77e8f91f15 100644
--- a/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V1QueryRoundtripBenchmark.java
+++ b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V1QueryRoundtripBenchmark.java
@@ -44,7 +44,7 @@
@Measurement(iterations = 5)
@Fork(2)
@BenchmarkMode(Mode.Throughput)
-@OutputTimeUnit(TimeUnit.MICROSECONDS)
+@OutputTimeUnit(TimeUnit.SECONDS)
public class V1QueryRoundtripBenchmark {
private ProtocolRoundtripServer server;
diff --git a/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V1RestJsonRoundtripBenchmark.java b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V1RestJsonRoundtripBenchmark.java
index 4283ac55a885..124bcda3452d 100644
--- a/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V1RestJsonRoundtripBenchmark.java
+++ b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V1RestJsonRoundtripBenchmark.java
@@ -51,7 +51,7 @@
@Measurement(iterations = 5)
@Fork(2)
@BenchmarkMode(Mode.Throughput)
-@OutputTimeUnit(TimeUnit.MICROSECONDS)
+@OutputTimeUnit(TimeUnit.SECONDS)
public class V1RestJsonRoundtripBenchmark {
private ProtocolRoundtripServer server;
diff --git a/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V1RestXmlRoundtripBenchmark.java b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V1RestXmlRoundtripBenchmark.java
index ac9968862e0a..78bd18462dc5 100644
--- a/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V1RestXmlRoundtripBenchmark.java
+++ b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V1RestXmlRoundtripBenchmark.java
@@ -56,7 +56,7 @@
@Measurement(iterations = 5)
@Fork(2)
@BenchmarkMode(Mode.Throughput)
-@OutputTimeUnit(TimeUnit.MICROSECONDS)
+@OutputTimeUnit(TimeUnit.SECONDS)
public class V1RestXmlRoundtripBenchmark {
private ProtocolRoundtripServer server;
diff --git a/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V2CborRoundtripBenchmark.java b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V2CborRoundtripBenchmark.java
index 13c92fc7a771..74af8b2563b0 100644
--- a/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V2CborRoundtripBenchmark.java
+++ b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V2CborRoundtripBenchmark.java
@@ -50,7 +50,7 @@
@Measurement(iterations = 5)
@Fork(2)
@BenchmarkMode(Mode.Throughput)
-@OutputTimeUnit(TimeUnit.MICROSECONDS)
+@OutputTimeUnit(TimeUnit.SECONDS)
public class V2CborRoundtripBenchmark {
private ProtocolRoundtripServer server;
diff --git a/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V2Ec2RoundtripBenchmark.java b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V2Ec2RoundtripBenchmark.java
index c52077bcadf3..e54090850fea 100644
--- a/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V2Ec2RoundtripBenchmark.java
+++ b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V2Ec2RoundtripBenchmark.java
@@ -45,7 +45,7 @@
@Measurement(iterations = 5)
@Fork(2)
@BenchmarkMode(Mode.Throughput)
-@OutputTimeUnit(TimeUnit.MICROSECONDS)
+@OutputTimeUnit(TimeUnit.SECONDS)
public class V2Ec2RoundtripBenchmark {
private ProtocolRoundtripServer server;
diff --git a/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V2JsonRoundtripBenchmark.java b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V2JsonRoundtripBenchmark.java
index 2c6453e9b79a..110c8c140637 100644
--- a/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V2JsonRoundtripBenchmark.java
+++ b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V2JsonRoundtripBenchmark.java
@@ -48,7 +48,7 @@
@Measurement(iterations = 5)
@Fork(2)
@BenchmarkMode(Mode.Throughput)
-@OutputTimeUnit(TimeUnit.MICROSECONDS)
+@OutputTimeUnit(TimeUnit.SECONDS)
public class V2JsonRoundtripBenchmark {
private ProtocolRoundtripServer server;
diff --git a/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V2QueryRoundtripBenchmark.java b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V2QueryRoundtripBenchmark.java
index a1bbcbcc1b79..d2757e96bcf0 100644
--- a/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V2QueryRoundtripBenchmark.java
+++ b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V2QueryRoundtripBenchmark.java
@@ -44,7 +44,7 @@
@Measurement(iterations = 5)
@Fork(2)
@BenchmarkMode(Mode.Throughput)
-@OutputTimeUnit(TimeUnit.MICROSECONDS)
+@OutputTimeUnit(TimeUnit.SECONDS)
public class V2QueryRoundtripBenchmark {
private ProtocolRoundtripServer server;
diff --git a/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V2RestJsonRoundtripBenchmark.java b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V2RestJsonRoundtripBenchmark.java
index f5dbfab3b38b..667d3ba419df 100644
--- a/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V2RestJsonRoundtripBenchmark.java
+++ b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V2RestJsonRoundtripBenchmark.java
@@ -51,7 +51,7 @@
@Measurement(iterations = 5)
@Fork(2)
@BenchmarkMode(Mode.Throughput)
-@OutputTimeUnit(TimeUnit.MICROSECONDS)
+@OutputTimeUnit(TimeUnit.SECONDS)
public class V2RestJsonRoundtripBenchmark {
private ProtocolRoundtripServer server;
diff --git a/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V2RestXmlRoundtripBenchmark.java b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V2RestXmlRoundtripBenchmark.java
index eee8fb19e3dc..f3b11e6e32b9 100644
--- a/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V2RestXmlRoundtripBenchmark.java
+++ b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V2RestXmlRoundtripBenchmark.java
@@ -56,7 +56,7 @@
@Measurement(iterations = 5)
@Fork(2)
@BenchmarkMode(Mode.Throughput)
-@OutputTimeUnit(TimeUnit.MICROSECONDS)
+@OutputTimeUnit(TimeUnit.SECONDS)
public class V2RestXmlRoundtripBenchmark {
private ProtocolRoundtripServer server;
From fa0445caaf07fb7b5d88130d9a38a8fe7be123fa Mon Sep 17 00:00:00 2001
From: RanVaknin <50976344+RanVaknin@users.noreply.github.com>
Date: Tue, 17 Mar 2026 13:57:48 -0700
Subject: [PATCH 6/7] Simplify servlet
---
.../protocol/ProtocolRoundtripServlet.java | 105 +-----------------
.../protocol/V1CborRoundtripBenchmark.java | 3 +-
.../protocol/V1Ec2RoundtripBenchmark.java | 3 +-
.../protocol/V1JsonRoundtripBenchmark.java | 3 +-
.../protocol/V1QueryRoundtripBenchmark.java | 3 +-
.../V1RestJsonRoundtripBenchmark.java | 3 +-
.../protocol/V1RestXmlRoundtripBenchmark.java | 6 +-
.../protocol/V2CborRoundtripBenchmark.java | 3 +-
.../protocol/V2Ec2RoundtripBenchmark.java | 3 +-
.../protocol/V2JsonRoundtripBenchmark.java | 3 +-
.../protocol/V2QueryRoundtripBenchmark.java | 3 +-
.../V2RestJsonRoundtripBenchmark.java | 3 +-
.../protocol/V2RestXmlRoundtripBenchmark.java | 6 +-
13 files changed, 17 insertions(+), 130 deletions(-)
diff --git a/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/ProtocolRoundtripServlet.java b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/ProtocolRoundtripServlet.java
index dd2a97f14ddb..ef4aeb9b9ca0 100644
--- a/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/ProtocolRoundtripServlet.java
+++ b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/ProtocolRoundtripServlet.java
@@ -16,116 +16,21 @@
package software.amazon.awssdk.benchmark.apicall.protocol;
import java.io.IOException;
-import java.io.OutputStream;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
-/**
- * Minimal servlet for protocol roundtrip benchmarks. Returns pre-loaded canned responses
- * with zero request inspection overhead. Routes are matched by URI prefix or X-Amz-Target header.
- */
class ProtocolRoundtripServlet extends HttpServlet {
+ private final byte[] body;
- private final Map targetRoutes = new ConcurrentHashMap<>();
- private final Map uriRoutes = new ConcurrentHashMap<>();
- private CannedResponse defaultResponse;
-
- /**
- * Register a route matched by X-Amz-Target header value.
- */
- ProtocolRoundtripServlet routeByTarget(String target, String contentType, byte[] body) {
- targetRoutes.put(target, new CannedResponse(contentType, body));
- return this;
- }
-
- /**
- * Register a route matched by URI prefix.
- */
- ProtocolRoundtripServlet routeByUri(String uriPrefix, String contentType, byte[] body) {
- uriRoutes.put(uriPrefix, new CannedResponse(contentType, body));
- return this;
- }
-
- /**
- * Register a route matched by URI prefix with additional response headers.
- */
- ProtocolRoundtripServlet routeByUri(String uriPrefix, String contentType, byte[] body,
- Map headers) {
- uriRoutes.put(uriPrefix, new CannedResponse(contentType, body, headers));
- return this;
- }
-
- /**
- * Default response when no route matches.
- */
- ProtocolRoundtripServlet defaultRoute(String contentType, byte[] body) {
- this.defaultResponse = new CannedResponse(contentType, body);
- return this;
+ ProtocolRoundtripServlet(byte[] body) {
+ this.body = body;
}
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws IOException {
- // Consume request body to simulate real HTTP exchange
- byte[] buf = new byte[8192];
- while (req.getInputStream().read(buf) != -1) {
- // drain
- }
-
- CannedResponse canned = resolve(req);
- if (canned == null) {
- resp.sendError(404);
- return;
- }
-
resp.setStatus(200);
- resp.setContentType(canned.contentType);
- resp.setContentLength(canned.body.length);
- resp.setHeader("x-amzn-RequestId", "benchmark-request-id");
- if (canned.headers != null) {
- canned.headers.forEach(resp::setHeader);
- }
- try (OutputStream os = resp.getOutputStream()) {
- os.write(canned.body);
- }
- }
-
- private CannedResponse resolve(HttpServletRequest req) {
- // Try X-Amz-Target first (JSON/CBOR protocols)
- String target = req.getHeader("X-Amz-Target");
- if (target != null) {
- CannedResponse r = targetRoutes.get(target);
- if (r != null) {
- return r;
- }
- }
-
- // Try URI prefix match (REST protocols)
- String uri = req.getRequestURI();
- for (Map.Entry entry : uriRoutes.entrySet()) {
- if (uri.contains(entry.getKey())) {
- return entry.getValue();
- }
- }
-
- return defaultResponse;
- }
-
- private static class CannedResponse {
- final String contentType;
- final byte[] body;
- final Map headers;
-
- CannedResponse(String contentType, byte[] body) {
- this(contentType, body, null);
- }
-
- CannedResponse(String contentType, byte[] body, Map headers) {
- this.contentType = contentType;
- this.body = body;
- this.headers = headers;
- }
+ resp.setContentLength(body.length);
+ resp.getOutputStream().write(body);
}
}
diff --git a/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V1CborRoundtripBenchmark.java b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V1CborRoundtripBenchmark.java
index 402bec59dc1c..547dfc64aa5d 100644
--- a/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V1CborRoundtripBenchmark.java
+++ b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V1CborRoundtripBenchmark.java
@@ -61,8 +61,7 @@ public class V1CborRoundtripBenchmark {
public void setup() throws Exception {
byte[] response = createCborResponseFixture();
- ProtocolRoundtripServlet servlet = new ProtocolRoundtripServlet()
- .defaultRoute("application/cbor", response);
+ ProtocolRoundtripServlet servlet = new ProtocolRoundtripServlet(response);
server = new ProtocolRoundtripServer(servlet);
server.start();
diff --git a/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V1Ec2RoundtripBenchmark.java b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V1Ec2RoundtripBenchmark.java
index aab3116f4a29..c4fe7638d684 100644
--- a/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V1Ec2RoundtripBenchmark.java
+++ b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V1Ec2RoundtripBenchmark.java
@@ -56,8 +56,7 @@ public class V1Ec2RoundtripBenchmark {
public void setup() throws Exception {
byte[] response = ProtocolRoundtripServer.loadFixture("ec2-protocol/describe-instances-response.xml");
- ProtocolRoundtripServlet servlet = new ProtocolRoundtripServlet()
- .defaultRoute("text/xml", response);
+ ProtocolRoundtripServlet servlet = new ProtocolRoundtripServlet(response);
server = new ProtocolRoundtripServer(servlet);
server.start();
diff --git a/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V1JsonRoundtripBenchmark.java b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V1JsonRoundtripBenchmark.java
index 0e345a761c3d..2214709b5ea7 100644
--- a/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V1JsonRoundtripBenchmark.java
+++ b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V1JsonRoundtripBenchmark.java
@@ -59,8 +59,7 @@ public class V1JsonRoundtripBenchmark {
public void setup() throws Exception {
byte[] response = ProtocolRoundtripServer.loadFixture("json-protocol/putitem-response.json");
- ProtocolRoundtripServlet servlet = new ProtocolRoundtripServlet()
- .routeByTarget("DynamoDB_20120810.PutItem", "application/x-amz-json-1.0", response);
+ ProtocolRoundtripServlet servlet = new ProtocolRoundtripServlet(response);
server = new ProtocolRoundtripServer(servlet);
server.start();
diff --git a/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V1QueryRoundtripBenchmark.java b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V1QueryRoundtripBenchmark.java
index cf77e8f91f15..03275d41be53 100644
--- a/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V1QueryRoundtripBenchmark.java
+++ b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V1QueryRoundtripBenchmark.java
@@ -55,8 +55,7 @@ public class V1QueryRoundtripBenchmark {
public void setup() throws Exception {
byte[] response = ProtocolRoundtripServer.loadFixture("query-protocol/assumerole-response.xml");
- ProtocolRoundtripServlet servlet = new ProtocolRoundtripServlet()
- .defaultRoute("text/xml", response);
+ ProtocolRoundtripServlet servlet = new ProtocolRoundtripServlet(response);
server = new ProtocolRoundtripServer(servlet);
server.start();
diff --git a/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V1RestJsonRoundtripBenchmark.java b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V1RestJsonRoundtripBenchmark.java
index 124bcda3452d..4db43a5ff2d0 100644
--- a/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V1RestJsonRoundtripBenchmark.java
+++ b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V1RestJsonRoundtripBenchmark.java
@@ -62,8 +62,7 @@ public class V1RestJsonRoundtripBenchmark {
public void setup() throws Exception {
byte[] response = ProtocolRoundtripServer.loadFixture("rest-json-protocol/createfunction-response.json");
- ProtocolRoundtripServlet servlet = new ProtocolRoundtripServlet()
- .routeByUri("/2015-03-31/functions", "application/json", response);
+ ProtocolRoundtripServlet servlet = new ProtocolRoundtripServlet(response);
server = new ProtocolRoundtripServer(servlet);
server.start();
diff --git a/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V1RestXmlRoundtripBenchmark.java b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V1RestXmlRoundtripBenchmark.java
index 78bd18462dc5..4d7c38624d02 100644
--- a/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V1RestXmlRoundtripBenchmark.java
+++ b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V1RestXmlRoundtripBenchmark.java
@@ -31,8 +31,6 @@
import com.amazonaws.services.cloudfront.model.Origins;
import com.amazonaws.services.cloudfront.model.S3OriginConfig;
import com.amazonaws.services.cloudfront.model.ViewerProtocolPolicy;
-import java.util.Collections;
-import java.util.Map;
import java.util.concurrent.TimeUnit;
import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.BenchmarkMode;
@@ -67,9 +65,7 @@ public class V1RestXmlRoundtripBenchmark {
public void setup() throws Exception {
byte[] response = ProtocolRoundtripServer.loadFixture("rest-xml-protocol/create-distribution-response.xml");
- Map headers = Collections.singletonMap("ETag", "E2QWRUHEXAMPLE");
- ProtocolRoundtripServlet servlet = new ProtocolRoundtripServlet()
- .routeByUri("/2020-05-31/distribution", "application/xml", response, headers);
+ ProtocolRoundtripServlet servlet = new ProtocolRoundtripServlet(response);
server = new ProtocolRoundtripServer(servlet);
server.start();
diff --git a/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V2CborRoundtripBenchmark.java b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V2CborRoundtripBenchmark.java
index 74af8b2563b0..0ab117fb6a3b 100644
--- a/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V2CborRoundtripBenchmark.java
+++ b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V2CborRoundtripBenchmark.java
@@ -61,8 +61,7 @@ public class V2CborRoundtripBenchmark {
public void setup() throws Exception {
byte[] response = createCborResponseFixture();
- ProtocolRoundtripServlet servlet = new ProtocolRoundtripServlet()
- .defaultRoute("application/cbor", response);
+ ProtocolRoundtripServlet servlet = new ProtocolRoundtripServlet(response);
server = new ProtocolRoundtripServer(servlet);
server.start();
diff --git a/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V2Ec2RoundtripBenchmark.java b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V2Ec2RoundtripBenchmark.java
index e54090850fea..8c7bda089a7c 100644
--- a/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V2Ec2RoundtripBenchmark.java
+++ b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V2Ec2RoundtripBenchmark.java
@@ -56,8 +56,7 @@ public class V2Ec2RoundtripBenchmark {
public void setup() throws Exception {
byte[] response = ProtocolRoundtripServer.loadFixture("ec2-protocol/describe-instances-response.xml");
- ProtocolRoundtripServlet servlet = new ProtocolRoundtripServlet()
- .defaultRoute("text/xml", response);
+ ProtocolRoundtripServlet servlet = new ProtocolRoundtripServlet(response);
server = new ProtocolRoundtripServer(servlet);
server.start();
diff --git a/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V2JsonRoundtripBenchmark.java b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V2JsonRoundtripBenchmark.java
index 110c8c140637..052df44b1111 100644
--- a/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V2JsonRoundtripBenchmark.java
+++ b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V2JsonRoundtripBenchmark.java
@@ -59,8 +59,7 @@ public class V2JsonRoundtripBenchmark {
public void setup() throws Exception {
byte[] response = ProtocolRoundtripServer.loadFixture("json-protocol/putitem-response.json");
- ProtocolRoundtripServlet servlet = new ProtocolRoundtripServlet()
- .routeByTarget("DynamoDB_20120810.PutItem", "application/x-amz-json-1.0", response);
+ ProtocolRoundtripServlet servlet = new ProtocolRoundtripServlet(response);
server = new ProtocolRoundtripServer(servlet);
server.start();
diff --git a/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V2QueryRoundtripBenchmark.java b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V2QueryRoundtripBenchmark.java
index d2757e96bcf0..b88ef43e9942 100644
--- a/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V2QueryRoundtripBenchmark.java
+++ b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V2QueryRoundtripBenchmark.java
@@ -55,8 +55,7 @@ public class V2QueryRoundtripBenchmark {
public void setup() throws Exception {
byte[] response = ProtocolRoundtripServer.loadFixture("query-protocol/assumerole-response.xml");
- ProtocolRoundtripServlet servlet = new ProtocolRoundtripServlet()
- .defaultRoute("text/xml", response);
+ ProtocolRoundtripServlet servlet = new ProtocolRoundtripServlet(response);
server = new ProtocolRoundtripServer(servlet);
server.start();
diff --git a/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V2RestJsonRoundtripBenchmark.java b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V2RestJsonRoundtripBenchmark.java
index 667d3ba419df..a8b562f2c086 100644
--- a/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V2RestJsonRoundtripBenchmark.java
+++ b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V2RestJsonRoundtripBenchmark.java
@@ -62,8 +62,7 @@ public class V2RestJsonRoundtripBenchmark {
public void setup() throws Exception {
byte[] response = ProtocolRoundtripServer.loadFixture("rest-json-protocol/createfunction-response.json");
- ProtocolRoundtripServlet servlet = new ProtocolRoundtripServlet()
- .routeByUri("/2015-03-31/functions", "application/json", response);
+ ProtocolRoundtripServlet servlet = new ProtocolRoundtripServlet(response);
server = new ProtocolRoundtripServer(servlet);
server.start();
diff --git a/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V2RestXmlRoundtripBenchmark.java b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V2RestXmlRoundtripBenchmark.java
index f3b11e6e32b9..db4cbcedcd04 100644
--- a/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V2RestXmlRoundtripBenchmark.java
+++ b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V2RestXmlRoundtripBenchmark.java
@@ -15,8 +15,6 @@
package software.amazon.awssdk.benchmark.apicall.protocol;
-import java.util.Collections;
-import java.util.Map;
import java.util.concurrent.TimeUnit;
import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.BenchmarkMode;
@@ -67,9 +65,7 @@ public class V2RestXmlRoundtripBenchmark {
public void setup() throws Exception {
byte[] response = ProtocolRoundtripServer.loadFixture("rest-xml-protocol/create-distribution-response.xml");
- Map headers = Collections.singletonMap("ETag", "E2QWRUHEXAMPLE");
- ProtocolRoundtripServlet servlet = new ProtocolRoundtripServlet()
- .routeByUri("/2020-05-31/distribution", "application/xml", response, headers);
+ ProtocolRoundtripServlet servlet = new ProtocolRoundtripServlet(response);
server = new ProtocolRoundtripServer(servlet);
server.start();
From 04975419c62b8223657dcaa9b719467d7df85b3f Mon Sep 17 00:00:00 2001
From: RanVaknin <50976344+RanVaknin@users.noreply.github.com>
Date: Wed, 18 Mar 2026 16:45:08 -0700
Subject: [PATCH 7/7] Move request creation into the benchmark runner
---
.../protocol/ProtocolRoundtripServlet.java | 5 +-
.../protocol/V1CborRoundtripBenchmark.java | 33 ++++---
.../protocol/V1Ec2RoundtripBenchmark.java | 17 ++--
.../protocol/V1JsonRoundtripBenchmark.java | 11 +--
.../protocol/V1QueryRoundtripBenchmark.java | 17 ++--
.../V1RestJsonRoundtripBenchmark.java | 27 +++---
.../protocol/V1RestXmlRoundtripBenchmark.java | 55 ++++++-----
.../protocol/V2CborRoundtripBenchmark.java | 45 +++++----
.../protocol/V2Ec2RoundtripBenchmark.java | 19 ++--
.../protocol/V2JsonRoundtripBenchmark.java | 13 ++-
.../protocol/V2QueryRoundtripBenchmark.java | 19 ++--
.../V2RestJsonRoundtripBenchmark.java | 43 +++++----
.../protocol/V2RestXmlRoundtripBenchmark.java | 93 +++++++++++--------
13 files changed, 203 insertions(+), 194 deletions(-)
diff --git a/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/ProtocolRoundtripServlet.java b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/ProtocolRoundtripServlet.java
index ef4aeb9b9ca0..abcce14534ad 100644
--- a/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/ProtocolRoundtripServlet.java
+++ b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/ProtocolRoundtripServlet.java
@@ -22,15 +22,18 @@
class ProtocolRoundtripServlet extends HttpServlet {
private final byte[] body;
+ private final String contentType;
- ProtocolRoundtripServlet(byte[] body) {
+ ProtocolRoundtripServlet(byte[] body, String contentType) {
this.body = body;
+ this.contentType = contentType;
}
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws IOException {
resp.setStatus(200);
resp.setContentLength(body.length);
+ resp.setContentType(contentType);
resp.getOutputStream().write(body);
}
}
diff --git a/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V1CborRoundtripBenchmark.java b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V1CborRoundtripBenchmark.java
index 547dfc64aa5d..eb7dfccee20c 100644
--- a/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V1CborRoundtripBenchmark.java
+++ b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V1CborRoundtripBenchmark.java
@@ -55,13 +55,12 @@ public class V1CborRoundtripBenchmark {
private ProtocolRoundtripServer server;
private AmazonCloudWatch client;
- private GetMetricDataRequest request;
@Setup(Level.Trial)
public void setup() throws Exception {
byte[] response = createCborResponseFixture();
- ProtocolRoundtripServlet servlet = new ProtocolRoundtripServlet(response);
+ ProtocolRoundtripServlet servlet = new ProtocolRoundtripServlet(response, "application/cbor");
server = new ProtocolRoundtripServer(servlet);
server.start();
@@ -71,10 +70,19 @@ public void setup() throws Exception {
server.getHttpUri().toString(), "us-east-1"))
.withCredentials(new AWSStaticCredentialsProvider(new BasicAWSCredentials("test", "test")))
.build();
+ }
+ @TearDown(Level.Trial)
+ public void tearDown() throws Exception {
+ client.shutdown();
+ server.stop();
+ }
+
+ @Benchmark
+ public void getMetricData(Blackhole bh) {
Date end = Date.from(java.time.Instant.parse("2026-03-09T00:00:00Z"));
Date start = Date.from(java.time.Instant.parse("2026-03-09T00:00:00Z").minusSeconds(3600));
- request = new GetMetricDataRequest()
+ GetMetricDataRequest request = new GetMetricDataRequest()
.withStartTime(start)
.withEndTime(end)
.withMaxDatapoints(1000)
@@ -82,22 +90,13 @@ public void setup() throws Exception {
new MetricDataQuery()
.withId("cpu")
.withMetricStat(new MetricStat()
- .withMetric(new Metric()
- .withNamespace("AWS/EC2")
- .withMetricName("CPUUtilization"))
- .withPeriod(300)
- .withStat("Average"))
+ .withMetric(new Metric()
+ .withNamespace("AWS/EC2")
+ .withMetricName("CPUUtilization"))
+ .withPeriod(300)
+ .withStat("Average"))
.withReturnData(true));
- }
- @TearDown(Level.Trial)
- public void tearDown() throws Exception {
- client.shutdown();
- server.stop();
- }
-
- @Benchmark
- public void getMetricData(Blackhole bh) {
bh.consume(client.getMetricData(request));
}
diff --git a/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V1Ec2RoundtripBenchmark.java b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V1Ec2RoundtripBenchmark.java
index c4fe7638d684..6ae6df995a99 100644
--- a/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V1Ec2RoundtripBenchmark.java
+++ b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V1Ec2RoundtripBenchmark.java
@@ -50,13 +50,12 @@ public class V1Ec2RoundtripBenchmark {
private ProtocolRoundtripServer server;
private AmazonEC2 client;
- private DescribeInstancesRequest request;
@Setup(Level.Trial)
public void setup() throws Exception {
byte[] response = ProtocolRoundtripServer.loadFixture("ec2-protocol/describe-instances-response.xml");
- ProtocolRoundtripServlet servlet = new ProtocolRoundtripServlet(response);
+ ProtocolRoundtripServlet servlet = new ProtocolRoundtripServlet(response, "text/xml");
server = new ProtocolRoundtripServer(servlet);
server.start();
@@ -66,13 +65,6 @@ public void setup() throws Exception {
server.getHttpUri().toString(), "us-east-1"))
.withCredentials(new AWSStaticCredentialsProvider(new BasicAWSCredentials("test", "test")))
.build();
-
- request = new DescribeInstancesRequest()
- .withInstanceIds("i-0abcdef1234567890")
- .withFilters(
- new Filter("instance-state-name").withValues("running"),
- new Filter("instance-type").withValues("m5.xlarge"))
- .withMaxResults(100);
}
@TearDown(Level.Trial)
@@ -83,6 +75,13 @@ public void tearDown() throws Exception {
@Benchmark
public void describeInstances(Blackhole bh) {
+ DescribeInstancesRequest request = new DescribeInstancesRequest()
+ .withInstanceIds("i-0abcdef1234567890")
+ .withFilters(
+ new Filter("instance-state-name").withValues("running"),
+ new Filter("instance-type").withValues("m5.xlarge"))
+ .withMaxResults(100);
+
bh.consume(client.describeInstances(request));
}
}
diff --git a/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V1JsonRoundtripBenchmark.java b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V1JsonRoundtripBenchmark.java
index 2214709b5ea7..58146050360c 100644
--- a/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V1JsonRoundtripBenchmark.java
+++ b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V1JsonRoundtripBenchmark.java
@@ -53,13 +53,12 @@ public class V1JsonRoundtripBenchmark {
private ProtocolRoundtripServer server;
private AmazonDynamoDB client;
- private PutItemRequest putItemRequest;
@Setup(Level.Trial)
public void setup() throws Exception {
byte[] response = ProtocolRoundtripServer.loadFixture("json-protocol/putitem-response.json");
- ProtocolRoundtripServlet servlet = new ProtocolRoundtripServlet(response);
+ ProtocolRoundtripServlet servlet = new ProtocolRoundtripServlet(response, "application/x-amz-json-1.0");
server = new ProtocolRoundtripServer(servlet);
server.start();
@@ -69,10 +68,6 @@ public void setup() throws Exception {
server.getHttpUri().toString(), "us-east-1"))
.withCredentials(new AWSStaticCredentialsProvider(new BasicAWSCredentials("test", "test")))
.build();
-
- putItemRequest = new PutItemRequest()
- .withTableName("benchmark-table")
- .withItem(itemMap());
}
@TearDown(Level.Trial)
@@ -83,6 +78,10 @@ public void tearDown() throws Exception {
@Benchmark
public void putItem(Blackhole bh) {
+ PutItemRequest putItemRequest = new PutItemRequest()
+ .withTableName("benchmark-table")
+ .withItem(itemMap());
+
bh.consume(client.putItem(putItemRequest));
}
diff --git a/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V1QueryRoundtripBenchmark.java b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V1QueryRoundtripBenchmark.java
index 03275d41be53..3da508d4ff5c 100644
--- a/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V1QueryRoundtripBenchmark.java
+++ b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V1QueryRoundtripBenchmark.java
@@ -49,13 +49,12 @@ public class V1QueryRoundtripBenchmark {
private ProtocolRoundtripServer server;
private AWSSecurityTokenService client;
- private AssumeRoleRequest request;
@Setup(Level.Trial)
public void setup() throws Exception {
byte[] response = ProtocolRoundtripServer.loadFixture("query-protocol/assumerole-response.xml");
- ProtocolRoundtripServlet servlet = new ProtocolRoundtripServlet(response);
+ ProtocolRoundtripServlet servlet = new ProtocolRoundtripServlet(response, "text/xml");
server = new ProtocolRoundtripServer(servlet);
server.start();
@@ -65,13 +64,6 @@ public void setup() throws Exception {
server.getHttpUri().toString(), "us-east-1"))
.withCredentials(new AWSStaticCredentialsProvider(new BasicAWSCredentials("test", "test")))
.build();
-
- request = new AssumeRoleRequest()
- .withRoleArn("arn:aws:iam::123456789012:role/benchmark-role")
- .withRoleSessionName("benchmark-session")
- .withDurationSeconds(3600)
- .withExternalId("benchmark-external-id")
- .withPolicy("{\"Version\":\"2012-10-17\"}");
}
@TearDown(Level.Trial)
@@ -82,6 +74,13 @@ public void tearDown() throws Exception {
@Benchmark
public void assumeRole(Blackhole bh) {
+ AssumeRoleRequest request = new AssumeRoleRequest()
+ .withRoleArn("arn:aws:iam::123456789012:role/benchmark-role")
+ .withRoleSessionName("benchmark-session")
+ .withDurationSeconds(3600)
+ .withExternalId("benchmark-external-id")
+ .withPolicy("{\"Version\":\"2012-10-17\"}");
+
bh.consume(client.assumeRole(request));
}
}
diff --git a/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V1RestJsonRoundtripBenchmark.java b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V1RestJsonRoundtripBenchmark.java
index 4db43a5ff2d0..5bc6d9ca080f 100644
--- a/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V1RestJsonRoundtripBenchmark.java
+++ b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V1RestJsonRoundtripBenchmark.java
@@ -56,13 +56,12 @@ public class V1RestJsonRoundtripBenchmark {
private ProtocolRoundtripServer server;
private AWSLambda client;
- private CreateFunctionRequest request;
@Setup(Level.Trial)
public void setup() throws Exception {
byte[] response = ProtocolRoundtripServer.loadFixture("rest-json-protocol/createfunction-response.json");
- ProtocolRoundtripServlet servlet = new ProtocolRoundtripServlet(response);
+ ProtocolRoundtripServlet servlet = new ProtocolRoundtripServlet(response, "application/json");
server = new ProtocolRoundtripServer(servlet);
server.start();
@@ -72,34 +71,34 @@ public void setup() throws Exception {
server.getHttpUri().toString(), "us-east-1"))
.withCredentials(new AWSStaticCredentialsProvider(new BasicAWSCredentials("test", "test")))
.build();
+ }
+ @TearDown(Level.Trial)
+ public void tearDown() throws Exception {
+ client.shutdown();
+ server.stop();
+ }
+
+ @Benchmark
+ public void createFunction(Blackhole bh) {
Map envVars = new HashMap<>();
envVars.put("ENV_VAR_1", "value1");
- request = new CreateFunctionRequest()
+ CreateFunctionRequest request = new CreateFunctionRequest()
.withFunctionName("benchmark-function")
.withRuntime(Runtime.Java8)
.withRole("arn:aws:iam::123456789012:role/lambda-role")
.withHandler("com.example.Handler::handleRequest")
.withCode(new FunctionCode()
- .withS3Bucket("my-deploy-bucket")
- .withS3Key("code/function.zip"))
+ .withS3Bucket("my-deploy-bucket")
+ .withS3Key("code/function.zip"))
.withDescription("Benchmark test function")
.withTimeout(30)
.withMemorySize(512)
.withPublish(false)
.withEnvironment(new Environment().withVariables(envVars))
.withTracingConfig(new TracingConfig().withMode(TracingMode.Active));
- }
- @TearDown(Level.Trial)
- public void tearDown() throws Exception {
- client.shutdown();
- server.stop();
- }
-
- @Benchmark
- public void createFunction(Blackhole bh) {
bh.consume(client.createFunction(request));
}
}
diff --git a/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V1RestXmlRoundtripBenchmark.java b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V1RestXmlRoundtripBenchmark.java
index 4d7c38624d02..ff42e19ada68 100644
--- a/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V1RestXmlRoundtripBenchmark.java
+++ b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V1RestXmlRoundtripBenchmark.java
@@ -59,13 +59,12 @@ public class V1RestXmlRoundtripBenchmark {
private ProtocolRoundtripServer server;
private AmazonCloudFront client;
- private CreateDistributionRequest request;
@Setup(Level.Trial)
public void setup() throws Exception {
byte[] response = ProtocolRoundtripServer.loadFixture("rest-xml-protocol/create-distribution-response.xml");
- ProtocolRoundtripServlet servlet = new ProtocolRoundtripServlet(response);
+ ProtocolRoundtripServlet servlet = new ProtocolRoundtripServlet(response, "text/xml");
server = new ProtocolRoundtripServer(servlet);
server.start();
@@ -75,32 +74,6 @@ public void setup() throws Exception {
server.getHttpUri().toString(), "us-east-1"))
.withCredentials(new AWSStaticCredentialsProvider(new BasicAWSCredentials("test", "test")))
.build();
-
- request = new CreateDistributionRequest()
- .withDistributionConfig(new DistributionConfig()
- .withCallerReference("benchmark-ref-2024")
- .withAliases(new Aliases()
- .withQuantity(2)
- .withItems("www.example.com", "cdn.example.com"))
- .withDefaultRootObject("index.html")
- .withOrigins(new Origins()
- .withQuantity(1)
- .withItems(new Origin()
- .withId("myS3Origin")
- .withDomainName("mybucket.s3.amazonaws.com")
- .withOriginPath("/production")
- .withS3OriginConfig(new S3OriginConfig()
- .withOriginAccessIdentity("origin-access-identity/cloudfront/E127EXAMPLE51Z"))))
- .withDefaultCacheBehavior(new DefaultCacheBehavior()
- .withTargetOriginId("myS3Origin")
- .withViewerProtocolPolicy(ViewerProtocolPolicy.RedirectToHttps)
- .withAllowedMethods(new AllowedMethods()
- .withQuantity(3)
- .withItems(Method.GET, Method.HEAD, Method.OPTIONS)
- .withCachedMethods(new CachedMethods()
- .withQuantity(2)
- .withItems(Method.GET, Method.HEAD)))
- .withCompress(true)));
}
@TearDown(Level.Trial)
@@ -111,6 +84,32 @@ public void tearDown() throws Exception {
@Benchmark
public void createDistribution(Blackhole bh) {
+ CreateDistributionRequest request = new CreateDistributionRequest()
+ .withDistributionConfig(new DistributionConfig()
+ .withCallerReference("benchmark-ref-2024")
+ .withAliases(new Aliases()
+ .withQuantity(2)
+ .withItems("www.example.com", "cdn.example.com"))
+ .withDefaultRootObject("index.html")
+ .withOrigins(new Origins()
+ .withQuantity(1)
+ .withItems(new Origin()
+ .withId("myS3Origin")
+ .withDomainName("mybucket.s3.amazonaws.com")
+ .withOriginPath("/production")
+ .withS3OriginConfig(new S3OriginConfig()
+ .withOriginAccessIdentity("origin-access-identity/cloudfront/E127EXAMPLE51Z"))))
+ .withDefaultCacheBehavior(new DefaultCacheBehavior()
+ .withTargetOriginId("myS3Origin")
+ .withViewerProtocolPolicy(ViewerProtocolPolicy.RedirectToHttps)
+ .withAllowedMethods(new AllowedMethods()
+ .withQuantity(3)
+ .withItems(Method.GET, Method.HEAD, Method.OPTIONS)
+ .withCachedMethods(new CachedMethods()
+ .withQuantity(2)
+ .withItems(Method.GET, Method.HEAD)))
+ .withCompress(true)));
+
bh.consume(client.createDistribution(request));
}
}
diff --git a/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V2CborRoundtripBenchmark.java b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V2CborRoundtripBenchmark.java
index 0ab117fb6a3b..f2f3e60a740b 100644
--- a/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V2CborRoundtripBenchmark.java
+++ b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V2CborRoundtripBenchmark.java
@@ -55,13 +55,12 @@ public class V2CborRoundtripBenchmark {
private ProtocolRoundtripServer server;
private CloudWatchClient client;
- private GetMetricDataRequest request;
@Setup(Level.Trial)
public void setup() throws Exception {
byte[] response = createCborResponseFixture();
- ProtocolRoundtripServlet servlet = new ProtocolRoundtripServlet(response);
+ ProtocolRoundtripServlet servlet = new ProtocolRoundtripServlet(response, "application/cbor");
server = new ProtocolRoundtripServer(servlet);
server.start();
@@ -72,27 +71,6 @@ public void setup() throws Exception {
.credentialsProvider(StaticCredentialsProvider.create(AwsBasicCredentials.create("test", "test")))
.httpClient(Apache5HttpClient.create())
.build();
-
- Instant end = Instant.parse("2026-03-09T00:00:00Z");
- Instant start = end.minusSeconds(3600);
- request = GetMetricDataRequest.builder()
- .startTime(start)
- .endTime(end)
- .maxDatapoints(1000)
- .metricDataQueries(
- MetricDataQuery.builder()
- .id("cpu")
- .metricStat(MetricStat.builder()
- .metric(Metric.builder()
- .namespace("AWS/EC2")
- .metricName("CPUUtilization")
- .build())
- .period(300)
- .stat("Average")
- .build())
- .returnData(true)
- .build())
- .build();
}
@TearDown(Level.Trial)
@@ -103,6 +81,27 @@ public void tearDown() throws Exception {
@Benchmark
public void getMetricData(Blackhole bh) {
+ Instant end = Instant.parse("2026-03-09T00:00:00Z");
+ Instant start = end.minusSeconds(3600);
+ GetMetricDataRequest request = GetMetricDataRequest.builder()
+ .startTime(start)
+ .endTime(end)
+ .maxDatapoints(1000)
+ .metricDataQueries(
+ MetricDataQuery.builder()
+ .id("cpu")
+ .metricStat(MetricStat.builder()
+ .metric(Metric.builder()
+ .namespace("AWS/EC2")
+ .metricName("CPUUtilization")
+ .build())
+ .period(300)
+ .stat("Average")
+ .build())
+ .returnData(true)
+ .build())
+ .build();
+
bh.consume(client.getMetricData(request));
}
diff --git a/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V2Ec2RoundtripBenchmark.java b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V2Ec2RoundtripBenchmark.java
index 8c7bda089a7c..3dfdd9cd74d2 100644
--- a/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V2Ec2RoundtripBenchmark.java
+++ b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V2Ec2RoundtripBenchmark.java
@@ -50,13 +50,12 @@ public class V2Ec2RoundtripBenchmark {
private ProtocolRoundtripServer server;
private Ec2Client client;
- private DescribeInstancesRequest request;
@Setup(Level.Trial)
public void setup() throws Exception {
byte[] response = ProtocolRoundtripServer.loadFixture("ec2-protocol/describe-instances-response.xml");
- ProtocolRoundtripServlet servlet = new ProtocolRoundtripServlet(response);
+ ProtocolRoundtripServlet servlet = new ProtocolRoundtripServlet(response, "text/xml");
server = new ProtocolRoundtripServer(servlet);
server.start();
@@ -67,14 +66,6 @@ public void setup() throws Exception {
.credentialsProvider(StaticCredentialsProvider.create(AwsBasicCredentials.create("test", "test")))
.httpClient(Apache5HttpClient.create())
.build();
-
- request = DescribeInstancesRequest.builder()
- .instanceIds("i-0abcdef1234567890")
- .filters(
- Filter.builder().name("instance-state-name").values("running").build(),
- Filter.builder().name("instance-type").values("m5.xlarge").build())
- .maxResults(100)
- .build();
}
@TearDown(Level.Trial)
@@ -85,6 +76,14 @@ public void tearDown() throws Exception {
@Benchmark
public void describeInstances(Blackhole bh) {
+ DescribeInstancesRequest request = DescribeInstancesRequest.builder()
+ .instanceIds("i-0abcdef1234567890")
+ .filters(
+ Filter.builder().name("instance-state-name").values("running").build(),
+ Filter.builder().name("instance-type").values("m5.xlarge").build())
+ .maxResults(100)
+ .build();
+
bh.consume(client.describeInstances(request));
}
}
diff --git a/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V2JsonRoundtripBenchmark.java b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V2JsonRoundtripBenchmark.java
index 052df44b1111..6d23fc581f6e 100644
--- a/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V2JsonRoundtripBenchmark.java
+++ b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V2JsonRoundtripBenchmark.java
@@ -53,13 +53,12 @@ public class V2JsonRoundtripBenchmark {
private ProtocolRoundtripServer server;
private DynamoDbClient client;
- private PutItemRequest putItemRequest;
@Setup(Level.Trial)
public void setup() throws Exception {
byte[] response = ProtocolRoundtripServer.loadFixture("json-protocol/putitem-response.json");
- ProtocolRoundtripServlet servlet = new ProtocolRoundtripServlet(response);
+ ProtocolRoundtripServlet servlet = new ProtocolRoundtripServlet(response, "application/x-amz-json-1.0");
server = new ProtocolRoundtripServer(servlet);
server.start();
@@ -70,11 +69,6 @@ public void setup() throws Exception {
.credentialsProvider(StaticCredentialsProvider.create(AwsBasicCredentials.create("test", "test")))
.httpClient(Apache5HttpClient.create())
.build();
-
- putItemRequest = PutItemRequest.builder()
- .tableName("benchmark-table")
- .item(itemMap())
- .build();
}
@TearDown(Level.Trial)
@@ -85,6 +79,11 @@ public void tearDown() throws Exception {
@Benchmark
public void putItem(Blackhole bh) {
+
+ PutItemRequest putItemRequest = PutItemRequest.builder()
+ .tableName("benchmark-table")
+ .item(itemMap())
+ .build();
bh.consume(client.putItem(putItemRequest));
}
diff --git a/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V2QueryRoundtripBenchmark.java b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V2QueryRoundtripBenchmark.java
index b88ef43e9942..aff4d9c23cd2 100644
--- a/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V2QueryRoundtripBenchmark.java
+++ b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V2QueryRoundtripBenchmark.java
@@ -49,13 +49,12 @@ public class V2QueryRoundtripBenchmark {
private ProtocolRoundtripServer server;
private StsClient client;
- private AssumeRoleRequest request;
@Setup(Level.Trial)
public void setup() throws Exception {
byte[] response = ProtocolRoundtripServer.loadFixture("query-protocol/assumerole-response.xml");
- ProtocolRoundtripServlet servlet = new ProtocolRoundtripServlet(response);
+ ProtocolRoundtripServlet servlet = new ProtocolRoundtripServlet(response, "text/xml");
server = new ProtocolRoundtripServer(servlet);
server.start();
@@ -66,14 +65,6 @@ public void setup() throws Exception {
.credentialsProvider(StaticCredentialsProvider.create(AwsBasicCredentials.create("test", "test")))
.httpClient(Apache5HttpClient.create())
.build();
-
- request = AssumeRoleRequest.builder()
- .roleArn("arn:aws:iam::123456789012:role/benchmark-role")
- .roleSessionName("benchmark-session")
- .durationSeconds(3600)
- .externalId("benchmark-external-id")
- .policy("{\"Version\":\"2012-10-17\"}")
- .build();
}
@TearDown(Level.Trial)
@@ -84,6 +75,14 @@ public void tearDown() throws Exception {
@Benchmark
public void assumeRole(Blackhole bh) {
+ AssumeRoleRequest request = AssumeRoleRequest.builder()
+ .roleArn("arn:aws:iam::123456789012:role/benchmark-role")
+ .roleSessionName("benchmark-session")
+ .durationSeconds(3600)
+ .externalId("benchmark-external-id")
+ .policy("{\"Version\":\"2012-10-17\"}")
+ .build();
+
bh.consume(client.assumeRole(request));
}
}
diff --git a/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V2RestJsonRoundtripBenchmark.java b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V2RestJsonRoundtripBenchmark.java
index a8b562f2c086..563ad7fd1dd3 100644
--- a/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V2RestJsonRoundtripBenchmark.java
+++ b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V2RestJsonRoundtripBenchmark.java
@@ -56,13 +56,12 @@ public class V2RestJsonRoundtripBenchmark {
private ProtocolRoundtripServer server;
private LambdaClient client;
- private CreateFunctionRequest request;
@Setup(Level.Trial)
public void setup() throws Exception {
byte[] response = ProtocolRoundtripServer.loadFixture("rest-json-protocol/createfunction-response.json");
- ProtocolRoundtripServlet servlet = new ProtocolRoundtripServlet(response);
+ ProtocolRoundtripServlet servlet = new ProtocolRoundtripServlet(response, "application/json");
server = new ProtocolRoundtripServer(servlet);
server.start();
@@ -73,26 +72,6 @@ public void setup() throws Exception {
.credentialsProvider(StaticCredentialsProvider.create(AwsBasicCredentials.create("test", "test")))
.httpClient(Apache5HttpClient.create())
.build();
-
- Map envVars = new HashMap<>();
- envVars.put("ENV_VAR_1", "value1");
-
- request = CreateFunctionRequest.builder()
- .functionName("benchmark-function")
- .runtime(Runtime.JAVA8)
- .role("arn:aws:iam::123456789012:role/lambda-role")
- .handler("com.example.Handler::handleRequest")
- .code(FunctionCode.builder()
- .s3Bucket("my-deploy-bucket")
- .s3Key("code/function.zip")
- .build())
- .description("Benchmark test function")
- .timeout(30)
- .memorySize(512)
- .publish(false)
- .environment(Environment.builder().variables(envVars).build())
- .tracingConfig(TracingConfig.builder().mode(TracingMode.ACTIVE).build())
- .build();
}
@TearDown(Level.Trial)
@@ -103,6 +82,26 @@ public void tearDown() throws Exception {
@Benchmark
public void createFunction(Blackhole bh) {
+ Map envVars = new HashMap<>();
+ envVars.put("ENV_VAR_1", "value1");
+
+ CreateFunctionRequest request = CreateFunctionRequest.builder()
+ .functionName("benchmark-function")
+ .runtime(Runtime.JAVA8)
+ .role("arn:aws:iam::123456789012:role/lambda-role")
+ .handler("com.example.Handler::handleRequest")
+ .code(FunctionCode.builder()
+ .s3Bucket("my-deploy-bucket")
+ .s3Key("code/function.zip")
+ .build())
+ .description("Benchmark test function")
+ .timeout(30)
+ .memorySize(512)
+ .publish(false)
+ .environment(Environment.builder().variables(envVars).build())
+ .tracingConfig(TracingConfig.builder().mode(TracingMode.ACTIVE).build())
+ .build();
+
bh.consume(client.createFunction(request));
}
}
diff --git a/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V2RestXmlRoundtripBenchmark.java b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V2RestXmlRoundtripBenchmark.java
index db4cbcedcd04..04cdea1b56ef 100644
--- a/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V2RestXmlRoundtripBenchmark.java
+++ b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/apicall/protocol/V2RestXmlRoundtripBenchmark.java
@@ -59,13 +59,12 @@ public class V2RestXmlRoundtripBenchmark {
private ProtocolRoundtripServer server;
private CloudFrontClient client;
- private CreateDistributionRequest request;
@Setup(Level.Trial)
public void setup() throws Exception {
byte[] response = ProtocolRoundtripServer.loadFixture("rest-xml-protocol/create-distribution-response.xml");
- ProtocolRoundtripServlet servlet = new ProtocolRoundtripServlet(response);
+ ProtocolRoundtripServlet servlet = new ProtocolRoundtripServlet(response, "text/xml");
server = new ProtocolRoundtripServer(servlet);
server.start();
@@ -73,44 +72,11 @@ public void setup() throws Exception {
client = CloudFrontClient.builder()
.endpointOverride(server.getHttpUri())
.region(Region.US_EAST_1)
- .credentialsProvider(StaticCredentialsProvider.create(AwsBasicCredentials.create("test", "test")))
+ .credentialsProvider(
+ StaticCredentialsProvider.create(
+ AwsBasicCredentials.create("test", "test")))
.httpClient(Apache5HttpClient.create())
.build();
-
- request = CreateDistributionRequest.builder()
- .distributionConfig(DistributionConfig.builder()
- .callerReference("benchmark-ref-2024")
- .aliases(Aliases.builder()
- .quantity(2)
- .items("www.example.com", "cdn.example.com")
- .build())
- .defaultRootObject("index.html")
- .origins(Origins.builder()
- .quantity(1)
- .items(Origin.builder()
- .id("myS3Origin")
- .domainName("mybucket.s3.amazonaws.com")
- .originPath("/production")
- .s3OriginConfig(S3OriginConfig.builder()
- .originAccessIdentity("origin-access-identity/cloudfront/E127EXAMPLE51Z")
- .build())
- .build())
- .build())
- .defaultCacheBehavior(DefaultCacheBehavior.builder()
- .targetOriginId("myS3Origin")
- .viewerProtocolPolicy(ViewerProtocolPolicy.REDIRECT_TO_HTTPS)
- .allowedMethods(AllowedMethods.builder()
- .quantity(3)
- .items(Method.GET, Method.HEAD, Method.OPTIONS)
- .cachedMethods(CachedMethods.builder()
- .quantity(2)
- .items(Method.GET, Method.HEAD)
- .build())
- .build())
- .compress(true)
- .build())
- .build())
- .build();
}
@TearDown(Level.Trial)
@@ -121,6 +87,57 @@ public void tearDown() throws Exception {
@Benchmark
public void createDistribution(Blackhole bh) {
+ S3OriginConfig s3Config = S3OriginConfig.builder()
+ .originAccessIdentity(
+ "origin-access-identity/cloudfront/E127EXAMPLE51Z")
+ .build();
+
+ Origin origin = Origin.builder()
+ .id("myS3Origin")
+ .domainName("mybucket.s3.amazonaws.com")
+ .originPath("/production")
+ .s3OriginConfig(s3Config)
+ .build();
+
+ CachedMethods cached = CachedMethods.builder()
+ .quantity(2)
+ .items(Method.GET, Method.HEAD)
+ .build();
+
+ AllowedMethods allowed = AllowedMethods.builder()
+ .quantity(3)
+ .items(Method.GET, Method.HEAD, Method.OPTIONS)
+ .cachedMethods(cached)
+ .build();
+
+ DefaultCacheBehavior cacheBehavior =
+ DefaultCacheBehavior.builder()
+ .targetOriginId("myS3Origin")
+ .viewerProtocolPolicy(
+ ViewerProtocolPolicy.REDIRECT_TO_HTTPS)
+ .allowedMethods(allowed)
+ .compress(true)
+ .build();
+
+ DistributionConfig config = DistributionConfig.builder()
+ .callerReference("benchmark-ref-2024")
+ .aliases(Aliases.builder()
+ .quantity(2)
+ .items("www.example.com", "cdn.example.com")
+ .build())
+ .defaultRootObject("index.html")
+ .origins(Origins.builder()
+ .quantity(1)
+ .items(origin)
+ .build())
+ .defaultCacheBehavior(cacheBehavior)
+ .build();
+
+ CreateDistributionRequest request =
+ CreateDistributionRequest.builder()
+ .distributionConfig(config)
+ .build();
+
bh.consume(client.createDistribution(request));
}
}