1 /* 2 * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"). 5 * You may not use this file except in compliance with the License. 6 * A copy of the License is located at 7 * 8 * http://aws.amazon.com/apache2.0 9 * 10 * or in the "license" file accompanying this file. This file is distributed 11 * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 12 * express or implied. See the License for the specific language governing 13 * permissions and limitations under the License. 14 */ 15 16 package software.amazon.awssdk.benchmark.apicall.httpclient.sync; 17 18 import static software.amazon.awssdk.benchmark.utils.BenchmarkConstant.CONCURRENT_CALLS; 19 import static software.amazon.awssdk.benchmark.utils.BenchmarkUtils.awaitCountdownLatchUninterruptibly; 20 import static software.amazon.awssdk.benchmark.utils.BenchmarkUtils.countDownUponCompletion; 21 import static software.amazon.awssdk.benchmark.utils.BenchmarkUtils.trustAllTlsAttributeMapBuilder; 22 23 import java.util.concurrent.CompletableFuture; 24 import java.util.concurrent.CountDownLatch; 25 import java.util.concurrent.ExecutorService; 26 import java.util.concurrent.Executors; 27 import java.util.concurrent.TimeUnit; 28 import org.openjdk.jmh.annotations.Benchmark; 29 import org.openjdk.jmh.annotations.BenchmarkMode; 30 import org.openjdk.jmh.annotations.Fork; 31 import org.openjdk.jmh.annotations.Level; 32 import org.openjdk.jmh.annotations.Measurement; 33 import org.openjdk.jmh.annotations.Mode; 34 import org.openjdk.jmh.annotations.OperationsPerInvocation; 35 import org.openjdk.jmh.annotations.Scope; 36 import org.openjdk.jmh.annotations.Setup; 37 import org.openjdk.jmh.annotations.State; 38 import org.openjdk.jmh.annotations.TearDown; 39 import org.openjdk.jmh.annotations.Warmup; 40 import org.openjdk.jmh.infra.Blackhole; 41 import org.openjdk.jmh.profile.StackProfiler; 42 import org.openjdk.jmh.runner.Runner; 43 import org.openjdk.jmh.runner.options.Options; 44 import org.openjdk.jmh.runner.options.OptionsBuilder; 45 import software.amazon.awssdk.benchmark.apicall.httpclient.SdkHttpClientBenchmark; 46 import software.amazon.awssdk.benchmark.utils.MockServer; 47 import software.amazon.awssdk.http.SdkHttpClient; 48 import software.amazon.awssdk.http.crt.AwsCrtHttpClient; 49 import software.amazon.awssdk.regions.Region; 50 import software.amazon.awssdk.services.protocolrestjson.ProtocolRestJsonClient; 51 52 /** 53 * Benchmarking for running with different http clients. 54 */ 55 @State(Scope.Benchmark) 56 @Warmup(iterations = 3, time = 15, timeUnit = TimeUnit.SECONDS) 57 @Measurement(iterations = 5, time = 10, timeUnit = TimeUnit.SECONDS) 58 @Fork(2) // To reduce difference between each run 59 @BenchmarkMode(Mode.Throughput) 60 public class CrtHttpClientBenchmark implements SdkHttpClientBenchmark { 61 62 private MockServer mockServer; 63 private SdkHttpClient sdkHttpClient; 64 private ProtocolRestJsonClient client; 65 private ExecutorService executorService; 66 67 @Setup(Level.Trial) setup()68 public void setup() throws Exception { 69 mockServer = new MockServer(); 70 mockServer.start(); 71 sdkHttpClient = AwsCrtHttpClient.builder() 72 .buildWithDefaults(trustAllTlsAttributeMapBuilder().build()); 73 client = ProtocolRestJsonClient.builder() 74 .endpointOverride(mockServer.getHttpsUri()) 75 .region(Region.US_EAST_1) 76 .httpClient(sdkHttpClient) 77 .build(); 78 executorService = Executors.newFixedThreadPool(CONCURRENT_CALLS); 79 80 client.allTypes(); 81 } 82 83 @TearDown(Level.Trial) tearDown()84 public void tearDown() throws Exception { 85 executorService.shutdown(); 86 mockServer.stop(); 87 sdkHttpClient.close(); 88 client.close(); 89 } 90 91 @Benchmark 92 @Override sequentialApiCall(Blackhole blackhole)93 public void sequentialApiCall(Blackhole blackhole) { 94 blackhole.consume(client.allTypes()); 95 } 96 97 @Benchmark 98 @Override 99 @OperationsPerInvocation(CONCURRENT_CALLS) concurrentApiCall(Blackhole blackhole)100 public void concurrentApiCall(Blackhole blackhole) { 101 CountDownLatch countDownLatch = new CountDownLatch(CONCURRENT_CALLS); 102 for (int i = 0; i < CONCURRENT_CALLS; i++) { 103 countDownUponCompletion(blackhole, 104 CompletableFuture.runAsync(() -> client.allTypes(), executorService), countDownLatch); 105 } 106 107 awaitCountdownLatchUninterruptibly(countDownLatch, 10, TimeUnit.SECONDS); 108 } 109 main(String... args)110 public static void main(String... args) throws Exception { 111 112 Options opt = new OptionsBuilder() 113 .include(CrtHttpClientBenchmark.class.getSimpleName() + ".concurrentApiCall") 114 .addProfiler(StackProfiler.class) 115 .build(); 116 new Runner(opt).run(); 117 } 118 } 119