• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.enhanced.dynamodb;
17 
18 import static software.amazon.awssdk.core.client.config.SdkClientOption.ENDPOINT;
19 
20 import java.io.IOException;
21 import java.io.UncheckedIOException;
22 import java.net.URI;
23 import java.util.Map;
24 import org.openjdk.jmh.annotations.Benchmark;
25 import org.openjdk.jmh.annotations.BenchmarkMode;
26 import org.openjdk.jmh.annotations.Fork;
27 import org.openjdk.jmh.annotations.Measurement;
28 import org.openjdk.jmh.annotations.Mode;
29 import org.openjdk.jmh.annotations.Param;
30 import org.openjdk.jmh.annotations.Scope;
31 import org.openjdk.jmh.annotations.Setup;
32 import org.openjdk.jmh.annotations.State;
33 import org.openjdk.jmh.annotations.Warmup;
34 import org.openjdk.jmh.infra.Blackhole;
35 import software.amazon.awssdk.auth.credentials.AwsBasicCredentials;
36 import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider;
37 import software.amazon.awssdk.benchmark.utils.MockHttpClient;
38 import software.amazon.awssdk.core.client.config.SdkClientConfiguration;
39 import software.amazon.awssdk.core.interceptor.Context;
40 import software.amazon.awssdk.core.interceptor.ExecutionAttributes;
41 import software.amazon.awssdk.core.interceptor.ExecutionInterceptor;
42 import software.amazon.awssdk.enhanced.dynamodb.DynamoDbEnhancedClient;
43 import software.amazon.awssdk.enhanced.dynamodb.DynamoDbTable;
44 import software.amazon.awssdk.enhanced.dynamodb.Key;
45 import software.amazon.awssdk.enhanced.dynamodb.TableSchema;
46 import software.amazon.awssdk.protocols.json.AwsJsonProtocol;
47 import software.amazon.awssdk.protocols.json.AwsJsonProtocolFactory;
48 import software.amazon.awssdk.services.dynamodb.DynamoDbClient;
49 import software.amazon.awssdk.services.dynamodb.model.AttributeValue;
50 import software.amazon.awssdk.services.dynamodb.model.DynamoDbException;
51 import software.amazon.awssdk.services.dynamodb.model.GetItemRequest;
52 import software.amazon.awssdk.services.dynamodb.model.PutItemRequest;
53 import software.amazon.awssdk.services.dynamodb.transform.PutItemRequestMarshaller;
54 import software.amazon.awssdk.utils.IoUtils;
55 
56 @BenchmarkMode(Mode.Throughput)
57 @Warmup(iterations = 5)
58 @Measurement(iterations = 5)
59 @Fork(2)
60 @State(Scope.Benchmark)
61 public class EnhancedClientGetOverheadBenchmark {
62     private static final AwsJsonProtocolFactory JSON_PROTOCOL_FACTORY = AwsJsonProtocolFactory
63             .builder()
64             .clientConfiguration(SdkClientConfiguration.builder()
65                     .option(ENDPOINT, URI.create("https://dynamodb.amazonaws.com"))
66                     .build())
67             .defaultServiceExceptionSupplier(DynamoDbException::builder)
68             .protocol(AwsJsonProtocol.AWS_JSON)
69             .protocolVersion("1.0")
70             .build();
71 
72     private static final PutItemRequestMarshaller PUT_ITEM_REQUEST_MARSHALLER =
73             new PutItemRequestMarshaller(JSON_PROTOCOL_FACTORY);
74 
75     private static final V2ItemFactory ITEM_FACTORY = new V2ItemFactory();
76 
77     private final Key testKey = Key.builder().partitionValue("key").build();
78 
79 
80     @Benchmark
lowLevelGet(TestState s)81     public Object lowLevelGet(TestState s) {
82         return s.dynamoDb.getItem(GetItemRequest.builder().build());
83     }
84 
85     @Benchmark
enhanceGet(TestState s)86     public Object enhanceGet(TestState s) {
87         return s.table.getItem(testKey);
88     }
89 
90     @State(Scope.Benchmark)
91     public static class TestState {
92         private DynamoDbClient dynamoDb;
93 
94         @Param({"TINY", "SMALL", "HUGE", "HUGE_FLAT"})
95         private TestItem testItem;
96 
97         private DynamoDbTable table;
98 
99         @Setup
setup(Blackhole bh)100         public void setup(Blackhole bh) {
101             dynamoDb = DynamoDbClient.builder()
102                     .credentialsProvider(StaticCredentialsProvider.create(
103                             AwsBasicCredentials.create("akid", "skid")))
104                     .httpClient(new MockHttpClient(testItem.responseContent, "{}"))
105                     .overrideConfiguration(o -> o.addExecutionInterceptor(new ExecutionInterceptor() {
106                         @Override
107                         public void afterUnmarshalling(Context.AfterUnmarshalling context,
108                                                        ExecutionAttributes executionAttributes) {
109                             bh.consume(context);
110                             bh.consume(executionAttributes);
111                         }
112                     }))
113                     .build();
114 
115             DynamoDbEnhancedClient ddbEnh = DynamoDbEnhancedClient.builder()
116                     .dynamoDbClient(dynamoDb)
117                     .build();
118 
119             table = ddbEnh.table(testItem.name(), testItem.tableSchema);
120         }
121     }
122 
123     public enum TestItem {
124         TINY(marshall(ITEM_FACTORY.tiny()), V2ItemFactory.TINY_BEAN_TABLE_SCHEMA),
125         SMALL(marshall(ITEM_FACTORY.small()), V2ItemFactory.SMALL_BEAN_TABLE_SCHEMA),
126         HUGE(marshall(ITEM_FACTORY.huge()), V2ItemFactory.HUGE_BEAN_TABLE_SCHEMA),
127         HUGE_FLAT(marshall(ITEM_FACTORY.hugeFlat()), V2ItemFactory.HUGE_BEAN_FLAT_TABLE_SCHEMA)
128         ;
129 
130         private String responseContent;
131         private TableSchema tableSchema;
132 
TestItem(String responseContent, TableSchema tableSchema)133         TestItem(String responseContent, TableSchema tableSchema) {
134             this.responseContent = responseContent;
135             this.tableSchema = tableSchema;
136         }
137     }
138 
marshall(Map<String, AttributeValue> item)139     private static String marshall(Map<String, AttributeValue> item) {
140         return PUT_ITEM_REQUEST_MARSHALLER.marshall(PutItemRequest.builder().item(item).build())
141                 .contentStreamProvider().map(cs -> {
142                     try {
143                         return IoUtils.toUtf8String(cs.newStream());
144                     } catch (IOException e) {
145                         throw new UncheckedIOException(e);
146                     }
147                 }).orElse(null);
148     }
149 }
150