From 452ca7fde971376f4f474bced33b4fcbb443e2ce Mon Sep 17 00:00:00 2001 From: RanVaknin <50976344+RanVaknin@users.noreply.github.com> Date: Mon, 17 Aug 2026 13:18:52 -0700 Subject: [PATCH 1/4] Improve PresignedRequest throughput by avoiding URI construction --- .../awscore/presigner/PresignedRequest.java | 11 +- .../presigner/PresignedRequestTest.java | 111 ++++++++++++++++++ test/sdk-benchmarks/pom.xml | 5 + .../presigner/S3PresignerBenchmark.java | 95 +++++++++++++++ 4 files changed, 220 insertions(+), 2 deletions(-) create mode 100644 core/aws-core/src/test/java/software/amazon/awssdk/awscore/presigner/PresignedRequestTest.java create mode 100644 test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/presigner/S3PresignerBenchmark.java diff --git a/core/aws-core/src/main/java/software/amazon/awssdk/awscore/presigner/PresignedRequest.java b/core/aws-core/src/main/java/software/amazon/awssdk/awscore/presigner/PresignedRequest.java index f3da23bf11f5..464007e5947a 100644 --- a/core/aws-core/src/main/java/software/amazon/awssdk/awscore/presigner/PresignedRequest.java +++ b/core/aws-core/src/main/java/software/amazon/awssdk/awscore/presigner/PresignedRequest.java @@ -27,6 +27,7 @@ import software.amazon.awssdk.core.SdkBytes; import software.amazon.awssdk.http.SdkHttpRequest; import software.amazon.awssdk.utils.Validate; +import software.amazon.awssdk.utils.http.SdkHttpUtils; /** @@ -49,7 +50,13 @@ protected PresignedRequest(DefaultBuilder builder) { this.signedHeaders = Validate.notEmpty(builder.signedHeaders, "signedHeaders"); this.signedPayload = builder.signedPayload; this.httpRequest = Validate.notNull(builder.httpRequest, "httpRequest"); - this.url = invokeSafely(httpRequest.getUri()::toURL); + this.url = toUrl(httpRequest); + } + + private static URL toUrl(SdkHttpRequest request) { + String queryString = request.encodedQueryParameters().map(query -> "?" + query).orElse(""); + int port = SdkHttpUtils.isUsingStandardPort(request.protocol(), request.port()) ? -1 : request.port(); + return invokeSafely(() -> new URL(request.protocol(), request.host(), port, request.encodedPath() + queryString)); } /** @@ -230,4 +237,4 @@ private B thisBuilder() { return (B) this; } } -} \ No newline at end of file +} diff --git a/core/aws-core/src/test/java/software/amazon/awssdk/awscore/presigner/PresignedRequestTest.java b/core/aws-core/src/test/java/software/amazon/awssdk/awscore/presigner/PresignedRequestTest.java new file mode 100644 index 000000000000..6c367ced04d1 --- /dev/null +++ b/core/aws-core/src/test/java/software/amazon/awssdk/awscore/presigner/PresignedRequestTest.java @@ -0,0 +1,111 @@ +/* + * 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.awscore.presigner; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.net.URI; +import java.time.Instant; +import java.util.Collections; +import org.junit.jupiter.api.Test; +import software.amazon.awssdk.http.SdkHttpFullRequest; +import software.amazon.awssdk.http.SdkHttpMethod; +import software.amazon.awssdk.http.SdkHttpRequest; + +class PresignedRequestTest { + @Test + void standardPortIsOmitted() throws Exception { + SdkHttpRequest httpRequest = requestBuilder() + .protocol("https") + .host("example.com") + .port(443) + .encodedPath("/resource") + .build(); + + assertEquivalentToUriConversion(httpRequest); + assertThat(presignedRequest(httpRequest).url().getPort()).isEqualTo(-1); + assertThat(presignedRequest(httpRequest).url()).hasToString("https://example.com/resource"); + } + + @Test + void customPortIsPreserved() throws Exception { + SdkHttpRequest httpRequest = requestBuilder() + .protocol("https") + .host("example.com") + .port(8443) + .encodedPath("/resource") + .build(); + + assertEquivalentToUriConversion(httpRequest); + assertThat(presignedRequest(httpRequest).url().getPort()).isEqualTo(8443); + assertThat(presignedRequest(httpRequest).url()).hasToString("https://example.com:8443/resource"); + } + + @Test + void encodedPathAndQueryValuesArePreserved() throws Exception { + SdkHttpRequest httpRequest = requestBuilder() + .protocol("https") + .host("example.com") + .encodedPath("/a%20path/%2Fvalue") + .putRawQueryParameter("key with space", "value/with?characters") + .build(); + + assertEquivalentToUriConversion(httpRequest); + assertThat(presignedRequest(httpRequest).url()) + .hasToString("https://example.com/a%20path/%2Fvalue?key%20with%20space=value%2Fwith%3Fcharacters"); + } + + @Test + void ipv6HostIsPreserved() throws Exception { + SdkHttpRequest httpRequest = requestBuilder() + .uri(URI.create("https://[2001:db8::1]:8443/resource")) + .build(); + + assertEquivalentToUriConversion(httpRequest); + assertThat(presignedRequest(httpRequest).url()) + .hasToString("https://[2001:db8::1]:8443/resource"); + } + + private static void assertEquivalentToUriConversion(SdkHttpRequest httpRequest) throws Exception { + assertThat(presignedRequest(httpRequest).url()).isEqualTo(httpRequest.getUri().toURL()); + } + + private static SdkHttpFullRequest.Builder requestBuilder() { + return SdkHttpFullRequest.builder().method(SdkHttpMethod.GET); + } + + private static TestPresignedRequest presignedRequest(SdkHttpRequest httpRequest) { + return new TestBuilder() + .expiration(Instant.EPOCH) + .isBrowserExecutable(true) + .signedHeaders(Collections.singletonMap("host", Collections.singletonList(httpRequest.host()))) + .httpRequest(httpRequest) + .build(); + } + + private static final class TestPresignedRequest extends PresignedRequest { + private TestPresignedRequest(TestBuilder builder) { + super(builder); + } + } + + private static final class TestBuilder extends PresignedRequest.DefaultBuilder { + @Override + public TestPresignedRequest build() { + return new TestPresignedRequest(this); + } + } +} diff --git a/test/sdk-benchmarks/pom.xml b/test/sdk-benchmarks/pom.xml index f784a7e11ff3..b88804822bf1 100644 --- a/test/sdk-benchmarks/pom.xml +++ b/test/sdk-benchmarks/pom.xml @@ -118,6 +118,11 @@ cloudfront ${awsjavasdk.version} + + software.amazon.awssdk + s3 + ${awsjavasdk.version} + software.amazon.awssdk sts diff --git a/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/presigner/S3PresignerBenchmark.java b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/presigner/S3PresignerBenchmark.java new file mode 100644 index 000000000000..f6c30909d2dc --- /dev/null +++ b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/presigner/S3PresignerBenchmark.java @@ -0,0 +1,95 @@ +/* + * 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.presigner; + +import java.net.URI; +import java.net.URL; +import java.time.Duration; +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.Level; +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 software.amazon.awssdk.auth.credentials.AwsBasicCredentials; +import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider; +import software.amazon.awssdk.regions.Region; +import software.amazon.awssdk.services.s3.S3Configuration; +import software.amazon.awssdk.services.s3.model.GetObjectRequest; +import software.amazon.awssdk.services.s3.presigner.S3Presigner; +import software.amazon.awssdk.services.s3.presigner.model.GetObjectPresignRequest; +import software.amazon.awssdk.services.s3.presigner.model.PresignedGetObjectRequest; + +@State(Scope.Thread) +public class S3PresignerBenchmark { + private static final String ENDPOINT = "s3.us-east-1.amazonaws.com"; + private static final String BUCKET = "java-sdk-presigner-benchmark"; + private static final String KEY = "reports/2026/representative object+name.txt"; + + private S3Presigner presigner; + private GetObjectPresignRequest request; + + @Setup(Level.Trial) + public void setup() { + presigner = S3Presigner.builder() + .region(Region.US_EAST_1) + .credentialsProvider(StaticCredentialsProvider.create( + AwsBasicCredentials.create("access-key", "secret-key"))) + .endpointOverride(URI.create("https://" + ENDPOINT)) + .serviceConfiguration(S3Configuration.builder() + .pathStyleAccessEnabled(true) + .build()) + .build(); + + GetObjectRequest getObjectRequest = + GetObjectRequest.builder() + .bucket(BUCKET) + .key(KEY) + .responseContentDisposition("attachment; filename=report.txt") + .versionId("benchmark-version") + .build(); + + request = GetObjectPresignRequest.builder() + .signatureDuration(Duration.ofMinutes(15)) + .getObjectRequest(getObjectRequest) + .build(); + + validate(presigner.presignGetObject(request)); + } + + @TearDown(Level.Trial) + public void tearDown() { + presigner.close(); + } + + @Benchmark + public PresignedGetObjectRequest presignGetObject() { + return presigner.presignGetObject(request); + } + + private static void validate(PresignedGetObjectRequest result) { + URL url = result.url(); + if (!"https".equals(url.getProtocol()) + || !ENDPOINT.equals(url.getHost()) + || !url.getPath().contains("/" + BUCKET + "/reports/2026/representative%20object%2Bname.txt") + || url.getQuery() == null + || !url.getQuery().contains("versionId=benchmark-version") + || !url.getQuery().contains("response-content-disposition=") + || !url.getQuery().contains("X-Amz-Signature=")) { + throw new IllegalStateException("S3 presigner benchmark sanity check failed: " + url); + } + } +} From d643a788fd65429b0d336d59df9fd0a7bc9059f5 Mon Sep 17 00:00:00 2001 From: RanVaknin <50976344+RanVaknin@users.noreply.github.com> Date: Mon, 17 Aug 2026 14:07:01 -0700 Subject: [PATCH 2/4] Remove validation code --- .../presigner/S3PresignerBenchmark.java | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/presigner/S3PresignerBenchmark.java b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/presigner/S3PresignerBenchmark.java index f6c30909d2dc..3f071938926f 100644 --- a/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/presigner/S3PresignerBenchmark.java +++ b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/presigner/S3PresignerBenchmark.java @@ -16,7 +16,6 @@ package software.amazon.awssdk.benchmark.presigner; import java.net.URI; -import java.net.URL; import java.time.Duration; import org.openjdk.jmh.annotations.Benchmark; import org.openjdk.jmh.annotations.Level; @@ -66,8 +65,6 @@ public void setup() { .signatureDuration(Duration.ofMinutes(15)) .getObjectRequest(getObjectRequest) .build(); - - validate(presigner.presignGetObject(request)); } @TearDown(Level.Trial) @@ -79,17 +76,4 @@ public void tearDown() { public PresignedGetObjectRequest presignGetObject() { return presigner.presignGetObject(request); } - - private static void validate(PresignedGetObjectRequest result) { - URL url = result.url(); - if (!"https".equals(url.getProtocol()) - || !ENDPOINT.equals(url.getHost()) - || !url.getPath().contains("/" + BUCKET + "/reports/2026/representative%20object%2Bname.txt") - || url.getQuery() == null - || !url.getQuery().contains("versionId=benchmark-version") - || !url.getQuery().contains("response-content-disposition=") - || !url.getQuery().contains("X-Amz-Signature=")) { - throw new IllegalStateException("S3 presigner benchmark sanity check failed: " + url); - } - } } From 3283a68590f52121844f4f00149d8a0b4f4ac1f2 Mon Sep 17 00:00:00 2001 From: RanVaknin <50976344+RanVaknin@users.noreply.github.com> Date: Mon, 17 Aug 2026 14:31:22 -0700 Subject: [PATCH 3/4] simplify benchmark --- .../presigner/PresignedRequestTest.java | 48 +++++++++++++++++-- .../presigner/S3PresignerBenchmark.java | 15 ++---- 2 files changed, 47 insertions(+), 16 deletions(-) diff --git a/core/aws-core/src/test/java/software/amazon/awssdk/awscore/presigner/PresignedRequestTest.java b/core/aws-core/src/test/java/software/amazon/awssdk/awscore/presigner/PresignedRequestTest.java index 6c367ced04d1..cb23273757d9 100644 --- a/core/aws-core/src/test/java/software/amazon/awssdk/awscore/presigner/PresignedRequestTest.java +++ b/core/aws-core/src/test/java/software/amazon/awssdk/awscore/presigner/PresignedRequestTest.java @@ -40,6 +40,33 @@ void standardPortIsOmitted() throws Exception { assertThat(presignedRequest(httpRequest).url()).hasToString("https://example.com/resource"); } + @Test + void standardHttpPortIsOmitted() throws Exception { + SdkHttpRequest httpRequest = requestBuilder() + .protocol("http") + .host("example.com") + .port(80) + .encodedPath("/resource") + .build(); + + assertEquivalentToUriConversion(httpRequest); + assertThat(presignedRequest(httpRequest).url().getPort()).isEqualTo(-1); + assertThat(presignedRequest(httpRequest).url()).hasToString("http://example.com/resource"); + } + + @Test + void implicitDefaultPortIsOmitted() throws Exception { + SdkHttpRequest httpRequest = requestBuilder() + .protocol("https") + .host("example.com") + .encodedPath("/resource") + .build(); + + assertThat(httpRequest.port()).isEqualTo(443); + assertEquivalentToUriConversion(httpRequest); + assertThat(presignedRequest(httpRequest).url().getPort()).isEqualTo(-1); + } + @Test void customPortIsPreserved() throws Exception { SdkHttpRequest httpRequest = requestBuilder() @@ -59,13 +86,25 @@ void encodedPathAndQueryValuesArePreserved() throws Exception { SdkHttpRequest httpRequest = requestBuilder() .protocol("https") .host("example.com") - .encodedPath("/a%20path/%2Fvalue") - .putRawQueryParameter("key with space", "value/with?characters") + .encodedPath("/a%20path/%2Fvalue%3Fquery%23fragment%25percent") + .putRawQueryParameter("key with space", "value/with?#%characters") .build(); assertEquivalentToUriConversion(httpRequest); assertThat(presignedRequest(httpRequest).url()) - .hasToString("https://example.com/a%20path/%2Fvalue?key%20with%20space=value%2Fwith%3Fcharacters"); + .hasToString("https://example.com/a%20path/%2Fvalue%3Fquery%23fragment%25percent" + + "?key%20with%20space=value%2Fwith%3F%23%25characters"); + } + + @Test + void emptyPathIsPreserved() throws Exception { + SdkHttpRequest httpRequest = requestBuilder() + .protocol("https") + .host("example.com") + .build(); + + assertEquivalentToUriConversion(httpRequest); + assertThat(presignedRequest(httpRequest).url()).hasToString("https://example.com"); } @Test @@ -80,7 +119,8 @@ void ipv6HostIsPreserved() throws Exception { } private static void assertEquivalentToUriConversion(SdkHttpRequest httpRequest) throws Exception { - assertThat(presignedRequest(httpRequest).url()).isEqualTo(httpRequest.getUri().toURL()); + assertThat(presignedRequest(httpRequest).url().toExternalForm()) + .isEqualTo(httpRequest.getUri().toURL().toExternalForm()); } private static SdkHttpFullRequest.Builder requestBuilder() { diff --git a/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/presigner/S3PresignerBenchmark.java b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/presigner/S3PresignerBenchmark.java index 3f071938926f..d6b1dd3f6903 100644 --- a/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/presigner/S3PresignerBenchmark.java +++ b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/presigner/S3PresignerBenchmark.java @@ -15,7 +15,6 @@ package software.amazon.awssdk.benchmark.presigner; -import java.net.URI; import java.time.Duration; import org.openjdk.jmh.annotations.Benchmark; import org.openjdk.jmh.annotations.Level; @@ -26,7 +25,6 @@ import software.amazon.awssdk.auth.credentials.AwsBasicCredentials; import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider; import software.amazon.awssdk.regions.Region; -import software.amazon.awssdk.services.s3.S3Configuration; import software.amazon.awssdk.services.s3.model.GetObjectRequest; import software.amazon.awssdk.services.s3.presigner.S3Presigner; import software.amazon.awssdk.services.s3.presigner.model.GetObjectPresignRequest; @@ -34,9 +32,8 @@ @State(Scope.Thread) public class S3PresignerBenchmark { - private static final String ENDPOINT = "s3.us-east-1.amazonaws.com"; - private static final String BUCKET = "java-sdk-presigner-benchmark"; - private static final String KEY = "reports/2026/representative object+name.txt"; + private static final String BUCKET = "bucket"; + private static final String KEY = "key"; private S3Presigner presigner; private GetObjectPresignRequest request; @@ -46,19 +43,13 @@ public void setup() { presigner = S3Presigner.builder() .region(Region.US_EAST_1) .credentialsProvider(StaticCredentialsProvider.create( - AwsBasicCredentials.create("access-key", "secret-key"))) - .endpointOverride(URI.create("https://" + ENDPOINT)) - .serviceConfiguration(S3Configuration.builder() - .pathStyleAccessEnabled(true) - .build()) + AwsBasicCredentials.create("dummykey", "dummysecret"))) .build(); GetObjectRequest getObjectRequest = GetObjectRequest.builder() .bucket(BUCKET) .key(KEY) - .responseContentDisposition("attachment; filename=report.txt") - .versionId("benchmark-version") .build(); request = GetObjectPresignRequest.builder() From 949d3ff4a51adc2f4a9bbf37df55c30d4ca3eca1 Mon Sep 17 00:00:00 2001 From: RanVaknin <50976344+RanVaknin@users.noreply.github.com> Date: Mon, 17 Aug 2026 14:56:48 -0700 Subject: [PATCH 4/4] Add test coverage --- .../presigner/PresignedRequestTest.java | 26 ++++++++++++++----- .../presigner/S3PresignerBenchmark.java | 10 +++++++ 2 files changed, 29 insertions(+), 7 deletions(-) diff --git a/core/aws-core/src/test/java/software/amazon/awssdk/awscore/presigner/PresignedRequestTest.java b/core/aws-core/src/test/java/software/amazon/awssdk/awscore/presigner/PresignedRequestTest.java index cb23273757d9..14be00015c9b 100644 --- a/core/aws-core/src/test/java/software/amazon/awssdk/awscore/presigner/PresignedRequestTest.java +++ b/core/aws-core/src/test/java/software/amazon/awssdk/awscore/presigner/PresignedRequestTest.java @@ -27,7 +27,7 @@ class PresignedRequestTest { @Test - void standardPortIsOmitted() throws Exception { + void url_withStandardHttpsPort_omitsPort() throws Exception { SdkHttpRequest httpRequest = requestBuilder() .protocol("https") .host("example.com") @@ -41,7 +41,7 @@ void standardPortIsOmitted() throws Exception { } @Test - void standardHttpPortIsOmitted() throws Exception { + void url_withStandardHttpPort_omitsPort() throws Exception { SdkHttpRequest httpRequest = requestBuilder() .protocol("http") .host("example.com") @@ -55,7 +55,7 @@ void standardHttpPortIsOmitted() throws Exception { } @Test - void implicitDefaultPortIsOmitted() throws Exception { + void url_withImplicitDefaultPort_omitsPort() throws Exception { SdkHttpRequest httpRequest = requestBuilder() .protocol("https") .host("example.com") @@ -68,7 +68,7 @@ void implicitDefaultPortIsOmitted() throws Exception { } @Test - void customPortIsPreserved() throws Exception { + void url_withCustomPort_preservesPort() throws Exception { SdkHttpRequest httpRequest = requestBuilder() .protocol("https") .host("example.com") @@ -82,7 +82,7 @@ void customPortIsPreserved() throws Exception { } @Test - void encodedPathAndQueryValuesArePreserved() throws Exception { + void url_withEncodedPathAndQuery_preservesEncodedValues() throws Exception { SdkHttpRequest httpRequest = requestBuilder() .protocol("https") .host("example.com") @@ -97,7 +97,7 @@ void encodedPathAndQueryValuesArePreserved() throws Exception { } @Test - void emptyPathIsPreserved() throws Exception { + void url_withEmptyPath_preservesEmptyPath() throws Exception { SdkHttpRequest httpRequest = requestBuilder() .protocol("https") .host("example.com") @@ -108,7 +108,19 @@ void emptyPathIsPreserved() throws Exception { } @Test - void ipv6HostIsPreserved() throws Exception { + void url_withEmptyPathAndQuery_preservesQuery() throws Exception { + SdkHttpRequest httpRequest = requestBuilder() + .protocol("https") + .host("example.com") + .putRawQueryParameter("foo", "bar") + .build(); + + assertEquivalentToUriConversion(httpRequest); + assertThat(presignedRequest(httpRequest).url()).hasToString("https://example.com?foo=bar"); + } + + @Test + void url_withIpv6Host_preservesHost() throws Exception { SdkHttpRequest httpRequest = requestBuilder() .uri(URI.create("https://[2001:db8::1]:8443/resource")) .build(); diff --git a/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/presigner/S3PresignerBenchmark.java b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/presigner/S3PresignerBenchmark.java index d6b1dd3f6903..68f814eac2b3 100644 --- a/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/presigner/S3PresignerBenchmark.java +++ b/test/sdk-benchmarks/src/main/java/software/amazon/awssdk/benchmark/presigner/S3PresignerBenchmark.java @@ -16,12 +16,18 @@ package software.amazon.awssdk.benchmark.presigner; import java.time.Duration; +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.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 software.amazon.awssdk.auth.credentials.AwsBasicCredentials; import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider; import software.amazon.awssdk.regions.Region; @@ -31,6 +37,10 @@ import software.amazon.awssdk.services.s3.presigner.model.PresignedGetObjectRequest; @State(Scope.Thread) +@Warmup(iterations = 5) +@Measurement(iterations = 5) +@Fork(2) +@BenchmarkMode(Mode.Throughput) public class S3PresignerBenchmark { private static final String BUCKET = "bucket"; private static final String KEY = "key";