33
33
import org .openjdk .jmh .annotations .Measurement ;
34
34
import org .openjdk .jmh .annotations .Mode ;
35
35
import org .openjdk .jmh .annotations .OperationsPerInvocation ;
36
+ import org .openjdk .jmh .annotations .Param ;
36
37
import org .openjdk .jmh .annotations .Scope ;
37
38
import org .openjdk .jmh .annotations .Setup ;
38
39
import org .openjdk .jmh .annotations .State ;
39
40
import org .openjdk .jmh .annotations .TearDown ;
40
41
import org .openjdk .jmh .annotations .Warmup ;
41
42
import org .openjdk .jmh .infra .Blackhole ;
43
+ import org .openjdk .jmh .profile .GCProfiler ;
42
44
import org .openjdk .jmh .profile .StackProfiler ;
43
45
import org .openjdk .jmh .results .RunResult ;
44
46
import org .openjdk .jmh .runner .Runner ;
45
47
import org .openjdk .jmh .runner .options .Options ;
46
48
import org .openjdk .jmh .runner .options .OptionsBuilder ;
47
49
import software .amazon .awssdk .benchmark .apicall .httpclient .SdkHttpClientBenchmark ;
48
50
import software .amazon .awssdk .benchmark .utils .MockServer ;
51
+ import software .amazon .awssdk .core .ResponseBytes ;
52
+ import software .amazon .awssdk .core .sync .RequestBody ;
53
+ import software .amazon .awssdk .core .sync .ResponseTransformer ;
49
54
import software .amazon .awssdk .http .SdkHttpClient ;
50
55
import software .amazon .awssdk .http .apache .ApacheHttpClient ;
56
+ import software .amazon .awssdk .http .apache5 .Apache5HttpClient ;
51
57
import software .amazon .awssdk .regions .Region ;
52
58
import software .amazon .awssdk .services .protocolrestjson .ProtocolRestJsonClient ;
59
+ import software .amazon .awssdk .services .protocolrestjson .model .StreamingInputOperationRequest ;
60
+ import software .amazon .awssdk .services .protocolrestjson .model .StreamingOutputOperationRequest ;
61
+ import software .amazon .awssdk .services .protocolrestjson .model .StreamingOutputOperationResponse ;
53
62
54
63
/**
55
- * Benchmarking for running with different http clients.
64
+ * Benchmarking for running with different Apache HTTP clients.
56
65
*/
57
66
@ State (Scope .Benchmark )
58
67
@ Warmup (iterations = 3 , time = 15 , timeUnit = TimeUnit .SECONDS )
61
70
@ BenchmarkMode (Mode .Throughput )
62
71
public class ApacheHttpClientBenchmark implements SdkHttpClientBenchmark {
63
72
73
+ private static final int STREAM_SIZE = 1024 * 1024 ; // 1MB
74
+ private static final byte [] STREAM_DATA = new byte [STREAM_SIZE ];
75
+
76
+ static {
77
+ // Initialize stream data
78
+ for (int i = 0 ; i < STREAM_SIZE ; i ++) {
79
+ STREAM_DATA [i ] = (byte ) (i % 256 );
80
+ }
81
+ }
82
+
83
+ @ Param ({"apache4" , "apache5" })
84
+ private String clientType ;
85
+
64
86
private MockServer mockServer ;
65
87
private SdkHttpClient sdkHttpClient ;
66
88
private ProtocolRestJsonClient client ;
@@ -70,8 +92,21 @@ public class ApacheHttpClientBenchmark implements SdkHttpClientBenchmark {
70
92
public void setup () throws Exception {
71
93
mockServer = new MockServer ();
72
94
mockServer .start ();
73
- sdkHttpClient = ApacheHttpClient .builder ()
74
- .buildWithDefaults (trustAllTlsAttributeMapBuilder ().build ());
95
+
96
+ // Create HTTP client based on parameter
97
+ switch (clientType ) {
98
+ case "apache4" :
99
+ sdkHttpClient = ApacheHttpClient .builder ()
100
+ .buildWithDefaults (trustAllTlsAttributeMapBuilder ().build ());
101
+ break ;
102
+ case "apache5" :
103
+ sdkHttpClient = Apache5HttpClient .builder ()
104
+ .buildWithDefaults (trustAllTlsAttributeMapBuilder ().build ());
105
+ break ;
106
+ default :
107
+ throw new IllegalArgumentException ("Unknown client type: " + clientType );
108
+ }
109
+
75
110
client = ProtocolRestJsonClient .builder ()
76
111
.endpointOverride (mockServer .getHttpsUri ())
77
112
.httpClient (sdkHttpClient )
@@ -109,12 +144,78 @@ public void concurrentApiCall(Blackhole blackhole) {
109
144
awaitCountdownLatchUninterruptibly (countDownLatch , 10 , TimeUnit .SECONDS );
110
145
}
111
146
112
- public static void main (String ... args ) throws Exception {
147
+ @ Benchmark
148
+ @ Override
149
+ public void streamingPutOperation (Blackhole blackhole ) {
150
+ StreamingInputOperationRequest request = StreamingInputOperationRequest .builder ()
151
+ .build ();
152
+ RequestBody requestBody = RequestBody .fromBytes (STREAM_DATA );
153
+
154
+ blackhole .consume (client .streamingInputOperation (request , requestBody ));
155
+ }
156
+
157
+ @ Benchmark
158
+ @ Override
159
+ @ OperationsPerInvocation (CONCURRENT_CALLS )
160
+ public void concurrentStreamingPutOperation (Blackhole blackhole ) {
161
+ CountDownLatch countDownLatch = new CountDownLatch (CONCURRENT_CALLS );
113
162
163
+ for (int i = 0 ; i < CONCURRENT_CALLS ; i ++) {
164
+ CompletableFuture <Void > future = CompletableFuture .runAsync (() -> {
165
+ StreamingInputOperationRequest request = StreamingInputOperationRequest .builder ()
166
+ .build ();
167
+ RequestBody requestBody = RequestBody .fromBytes (STREAM_DATA );
168
+ client .streamingInputOperation (request , requestBody );
169
+ }, executorService );
170
+
171
+ countDownUponCompletion (blackhole , future , countDownLatch );
172
+ }
173
+
174
+ awaitCountdownLatchUninterruptibly (countDownLatch , 10 , TimeUnit .SECONDS );
175
+ }
176
+
177
+ @ Benchmark
178
+ @ Override
179
+ public void streamingOutputOperation (Blackhole blackhole ) {
180
+ StreamingOutputOperationRequest request = StreamingOutputOperationRequest .builder ()
181
+ .build ();
182
+
183
+ ResponseBytes <StreamingOutputOperationResponse > responseBytes =
184
+ client .streamingOutputOperation (request , ResponseTransformer .toBytes ());
185
+
186
+ blackhole .consume (responseBytes .asByteArray ());
187
+ }
188
+
189
+ @ Benchmark
190
+ @ Override
191
+ @ OperationsPerInvocation (CONCURRENT_CALLS )
192
+ public void concurrentStreamingOutputOperation (Blackhole blackhole ) {
193
+ CountDownLatch countDownLatch = new CountDownLatch (CONCURRENT_CALLS );
194
+
195
+ for (int i = 0 ; i < CONCURRENT_CALLS ; i ++) {
196
+ CompletableFuture <Void > future = CompletableFuture .runAsync (() -> {
197
+ StreamingOutputOperationRequest request = StreamingOutputOperationRequest .builder ()
198
+ .build ();
199
+
200
+ ResponseBytes <StreamingOutputOperationResponse > responseBytes =
201
+ client .streamingOutputOperation (request , ResponseTransformer .toBytes ());
202
+
203
+ blackhole .consume (responseBytes .asByteArray ());
204
+ }, executorService );
205
+
206
+ countDownUponCompletion (blackhole , future , countDownLatch );
207
+ }
208
+
209
+ awaitCountdownLatchUninterruptibly (countDownLatch , 10 , TimeUnit .SECONDS );
210
+ }
211
+
212
+ public static void main (String ... args ) throws Exception {
114
213
Options opt = new OptionsBuilder ()
115
- .include (ApacheHttpClientBenchmark .class .getSimpleName () + ".concurrentApiCall" )
214
+ .include (ApacheHttpClientBenchmark .class .getSimpleName ())
116
215
.addProfiler (StackProfiler .class )
216
+ .addProfiler (GCProfiler .class )
117
217
.build ();
218
+
118
219
Collection <RunResult > run = new Runner (opt ).run ();
119
220
}
120
221
}
0 commit comments