Skip to content

Commit b71f4da

Browse files
Yimu-Yangjasdel
authored andcommitted
private/protocol: Add unmarshaler benchmarks (#334)
Adds benchmarks to the protocol marshalers for RESTXML, RESTJSON, REST, JSON and XML protocols.
1 parent 801e5ee commit b71f4da

File tree

5 files changed

+355
-0
lines changed

5 files changed

+355
-0
lines changed
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
package jsonutil_test
2+
3+
import (
4+
"bytes"
5+
"encoding/json"
6+
"github.com/aws/aws-sdk-go-v2/aws"
7+
"github.com/aws/aws-sdk-go-v2/private/protocol/json/jsonutil"
8+
"github.com/aws/aws-sdk-go-v2/service/dynamodb"
9+
"io/ioutil"
10+
"net/http"
11+
"testing"
12+
)
13+
14+
var (
15+
simpleJSON = []byte(`{"FooEnum": "foo", "ListEnums": ["0", "1"]}`)
16+
complexJSON = []byte(`{"Table":{"AttributeDefinitions":[{"AttributeName":"1","AttributeType":"N"}],"CreationDateTime":1.562054355238E9,"ItemCount":0,"KeySchema":[{"AttributeName":"1","KeyType":"HASH"}],"ProvisionedThroughput":{"NumberOfDecreasesToday":0,"ReadCapacityUnits":5,"WriteCapacityUnits":5},"TableArn":"arn:aws:dynamodb:us-west-2:183557167593:table/TestTable","TableId":"575d0be6-34e3-4843-838c-8e8e8d4ea2f7","TableName":"TestTable","TableSizeBytes":0,"TableStatus":"ACTIVE"}}`)
17+
)
18+
19+
type DataOutput struct {
20+
_ struct{} `type:"structure"`
21+
22+
FooEnum string `type:"string" enum:"true"`
23+
24+
ListEnums []string `type:"list"`
25+
}
26+
27+
func BenchmarkJSONUnmarshal_Simple(b *testing.B) {
28+
b.ResetTimer()
29+
for i := 0; i < b.N; i++ {
30+
req := getJSONResponseSimple()
31+
jsonutil.UnmarshalJSON(req.Data, req.HTTPResponse.Body)
32+
}
33+
}
34+
35+
func BenchmarkJSONUnmarshal_Complex(b *testing.B) {
36+
b.ResetTimer()
37+
for i := 0; i < b.N; i++ {
38+
req := getJSONResponseComplex()
39+
jsonutil.UnmarshalJSON(req.Data, req.HTTPResponse.Body)
40+
}
41+
}
42+
43+
func BenchmarkStdlibJSON_Unmarshal_Simple(b *testing.B) {
44+
b.ResetTimer()
45+
for i := 0; i < b.N; i++ {
46+
json.Unmarshal(simpleJSON, &DataOutput{})
47+
}
48+
}
49+
50+
func BenchmarkStdlibJSON_Unmarshal_Complex(b *testing.B) {
51+
b.ResetTimer()
52+
for i := 0; i < b.N; i++ {
53+
json.Unmarshal(complexJSON, &dynamodb.DescribeTableOutput{})
54+
}
55+
}
56+
57+
func getJSONResponseSimple() *aws.Request {
58+
buf := bytes.NewReader(simpleJSON)
59+
req := aws.Request{Data: &DataOutput{}, HTTPResponse: &http.Response{Body: ioutil.NopCloser(buf)}}
60+
return &req
61+
}
62+
63+
func getJSONResponseComplex() *aws.Request {
64+
buf := bytes.NewReader(complexJSON)
65+
req := aws.Request{Data: &dynamodb.DescribeTableOutput{}, HTTPResponse: &http.Response{Body: ioutil.NopCloser(buf)}}
66+
return &req
67+
}
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
package rest
2+
3+
import (
4+
"bytes"
5+
"github.com/aws/aws-sdk-go-v2/aws"
6+
"io/ioutil"
7+
"net/http"
8+
"testing"
9+
)
10+
11+
type DataOutput struct {
12+
_ struct{} `type:"structure"`
13+
14+
HeaderEnum string `location:"header" locationName:"x-amz-enum" type:"string" enum:"true"`
15+
16+
StatusCode int64 `location:"statusCode"`
17+
}
18+
19+
type DataOutput2 struct {
20+
_ struct{} `type:"structure" payload:"TestString"`
21+
22+
TestString *string `type:"string"`
23+
}
24+
25+
func BenchmarkRESTUnmarshalMeta(b *testing.B) {
26+
b.ResetTimer()
27+
for i := 0; i < b.N; i++ {
28+
UnmarshalMeta(getRESTMeta())
29+
}
30+
}
31+
32+
func BenchmarkRESTUnmarshal_Short(b *testing.B) {
33+
b.ResetTimer()
34+
for i := 0; i < b.N; i++ {
35+
Unmarshal(getRESTResponseShortREST())
36+
}
37+
}
38+
39+
func BenchmarkRESTUnmarshal_Long(b *testing.B) {
40+
b.ResetTimer()
41+
for i := 0; i < b.N; i++ {
42+
Unmarshal(getRESTResponseLongREST())
43+
}
44+
}
45+
46+
func getRESTMeta() *aws.Request {
47+
output := DataOutput{}
48+
req := aws.Request{Data: &output, HTTPResponse: &http.Response{StatusCode: 200, Header: http.Header{}}}
49+
req.HTTPResponse.Header.Set("x-amz-enum", "baz")
50+
return &req
51+
}
52+
53+
func getRESTResponseShortREST() *aws.Request {
54+
buf := bytes.NewReader([]byte("test_string"))
55+
req := aws.Request{Data: &DataOutput2{}, HTTPResponse: &http.Response{Body: ioutil.NopCloser(buf)}}
56+
return &req
57+
}
58+
59+
func getRESTResponseLongREST() *aws.Request {
60+
buf := bytes.NewReader([]byte("O8sxCe0h66aCwPY2gLAhmKPFVP9c5b0o6iViHf4G58JT5ugSPX8VvFj7KAk5ykjR4Xlq7MAzGFcaFRFMiSwDuSMHNCO7KiiE3Eud38zkq62uwlkLteORA1EZLfbnTO2QigizYAcbJQkTf3mDpJdxDOkpinAMOUTA3uGq1VqG2lrVu4D0vnCXUh6L8HzQ7vGRM0ydWpCdhefedJSDOuNr4PWvESEPFS3gAZYFFYhdJGyeF9NfyqrmAApog25pERNrd7cY5wkahx1bCh4wqkUchlwg795rbKpYIO4feYChnp94I0rtX7RNUfEksRuamEgvcdJODV8yWdI2TiBobkCUwB1avVixmo5frWIXPvQVPls1sfxlOKpgsP9dm3dKaxalUWcQVG7Nv5b3TXbh6IeXKivYtwEaHo2T2pFt39cfty6k2GEFAjxjDXBrw4ljsZv0HcA36XNvWOCoRblISa7CMV9J0QjQ3W1D0MfXqkygojpxcxgKNbyNR28oZmX3H0ZY4kz4NCj34tg0jCHzpj9KExZGLvinWF4IuR4gKi8usXp6j7q7ZqX2qf7bx9tWs3Ci3N7lnq5NPrBVSeHGyNmBHdVzFEPBFiFPyiFkLtSQFCS054WaDmR5m2DJK9gmY9gMxmnMDk6q2Vzdp1j8mgzFsjbhQWiKMuwIel9YKqDzijlxaNSJKd9UWvNs4CFewlzq4JP7VC7vfSkOmI0RmeTirey3KrCLzHCB1bizMhSxwkZZz745vvQMfYXZ14vw4KEsqQVKTldg74EQuLiEHjpxcJ5PPh31FxkkEPvq4AD9JcfB8b4Uead3ij20dCZ7qhDmKrJ2eTbP5mYpZdiymETpRtCtA6mbcTxeJQrtlJbUgJjVOixhTZOS6Qe3GTsLES8lKasGQPFWbPPE44Ot2vZJtmeFZfLyCTtzIIHNx00Zzv6aHh1I8rstQef3rKQ9yExELk4J6ckCmaPnBGsDX1U91hVrx2LsJ1h8dUNXEQzE"))
61+
req := aws.Request{Data: &DataOutput2{}, HTTPResponse: &http.Response{Body: ioutil.NopCloser(buf)}}
62+
return &req
63+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package restjson
2+
3+
import (
4+
"bytes"
5+
"github.com/aws/aws-sdk-go-v2/aws"
6+
"io/ioutil"
7+
"net/http"
8+
"testing"
9+
)
10+
11+
func BenchmarkRESTJSONUnmarshalError(b *testing.B) {
12+
b.ResetTimer()
13+
for i := 0; i < b.N; i++ {
14+
UnmarshalError(getRESTJSONError())
15+
}
16+
}
17+
18+
func getRESTJSONError() *aws.Request {
19+
buf := bytes.NewReader([]byte(`{"message":"test error message"}`))
20+
req := aws.Request{RequestID: "b25f48e8-84fd-11e6-80d9-574e0c4664cb",
21+
HTTPResponse: &http.Response{StatusCode: 404, Body: ioutil.NopCloser(buf), Header: http.Header{}}}
22+
req.HTTPResponse.Header.Set("X-Amzn-Errortype", "baz")
23+
return &req
24+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package restxml
2+
3+
import (
4+
"bytes"
5+
"github.com/aws/aws-sdk-go-v2/aws"
6+
"io/ioutil"
7+
"net/http"
8+
"testing"
9+
)
10+
11+
func BenchmarkRESTXMLUnmarshalError(b *testing.B) {
12+
b.ResetTimer()
13+
for i := 0; i < b.N; i++ {
14+
UnmarshalError(getRESTXMLError())
15+
}
16+
}
17+
18+
func getRESTXMLError() *aws.Request {
19+
buf := bytes.NewReader([]byte(`
20+
<ErrorResponse>
21+
<Error>
22+
<Code>baz</Code>
23+
<Message>test error message</Message>
24+
</Error>
25+
<RequestId>b25f48e8-84fd-11e6-80d9-574e0c4664cb</RequestId>
26+
</ErrorResponse>`))
27+
req := aws.Request{HTTPResponse: &http.Response{StatusCode: 404, Body: ioutil.NopCloser(buf), Header: http.Header{}}}
28+
req.HTTPResponse.Header.Set("X-Amzn-Errortype", "baz")
29+
return &req
30+
}
Lines changed: 171 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,171 @@
1+
package xmlutil_test
2+
3+
import (
4+
"bytes"
5+
"encoding/xml"
6+
"io/ioutil"
7+
"net/http"
8+
"testing"
9+
10+
"github.com/aws/aws-sdk-go-v2/aws"
11+
"github.com/aws/aws-sdk-go-v2/private/protocol/xml/xmlutil"
12+
"github.com/aws/aws-sdk-go-v2/service/ec2"
13+
)
14+
15+
type DataOutput struct {
16+
_ struct{} `type:"structure"`
17+
18+
FooEnum string `type:"string" enum:"true"`
19+
20+
ListEnums []string `type:"list"`
21+
}
22+
23+
func BenchmarkXMLUnmarshal_Simple(b *testing.B) {
24+
b.ResetTimer()
25+
for i := 0; i < b.N; i++ {
26+
req := getXMLResponseSimple()
27+
xmlutil.UnmarshalXML(req.Data, xml.NewDecoder(req.HTTPResponse.Body), "")
28+
}
29+
}
30+
31+
func BenchmarkXMLUnmarshal_Complex(b *testing.B) {
32+
b.ResetTimer()
33+
for i := 0; i < b.N; i++ {
34+
req := getXMLResponseComplex()
35+
xmlutil.UnmarshalXML(req.Data, xml.NewDecoder(req.HTTPResponse.Body), "")
36+
}
37+
}
38+
39+
func getXMLResponseSimple() *aws.Request {
40+
buf := bytes.NewReader([]byte("<OperationNameResponse><FooEnum>foo</FooEnum><ListEnums><member>0</member><member>1</member></ListEnums></OperationNameResponse>"))
41+
req := aws.Request{Data: &DataOutput{}, HTTPResponse: &http.Response{Body: ioutil.NopCloser(buf)}}
42+
return &req
43+
}
44+
45+
func getXMLResponseComplex() *aws.Request {
46+
buf := bytes.NewReader([]byte(`<?xml version="1.0" encoding="UTF-8"?>
47+
<DescribeInstancesResponse xmlns="http://ec2.amazonaws.com/doc/2016-11-15/">
48+
<requestId>7e2ca54c-e2af-4567-bb41-21632d2b839e</requestId>
49+
<reservationSet>
50+
<item>
51+
<reservationId>r-05e953f164a34c484</reservationId>
52+
<ownerId>183557167593</ownerId>
53+
<groupSet/>
54+
<instancesSet>
55+
<item>
56+
<instanceId>i-05805668ced0206f0</instanceId>
57+
<imageId>ami-082b5a644766e0e6f</imageId>
58+
<instanceState>
59+
<code>16</code>
60+
<name>running</name>
61+
</instanceState>
62+
<privateDnsName>ip-172-31-30-42.us-west-2.compute.internal</privateDnsName>
63+
<dnsName>ec2-34-219-17-124.us-west-2.compute.amazonaws.com</dnsName>
64+
<reason/>
65+
<keyName>ec2</keyName>
66+
<amiLaunchIndex>0</amiLaunchIndex>
67+
<productCodes/>
68+
<instanceType>t2.micro</instanceType>
69+
<launchTime>2019-07-01T21:15:47.000Z</launchTime>
70+
<placement>
71+
<availabilityZone>us-west-2a</availabilityZone>
72+
<groupName/>
73+
<tenancy>default</tenancy>
74+
</placement>
75+
<monitoring>
76+
<state>disabled</state>
77+
</monitoring>
78+
<subnetId>subnet-21959558</subnetId>
79+
<vpcId>vpc-1de55365</vpcId>
80+
<privateIpAddress>172.31.30.42</privateIpAddress>
81+
<ipAddress>34.219.17.124</ipAddress>
82+
<sourceDestCheck>true</sourceDestCheck>
83+
<groupSet>
84+
<item>
85+
<groupId>sg-02d1f51eb2fa52795</groupId>
86+
<groupName>launch-wizard-2</groupName>
87+
</item>
88+
</groupSet>
89+
<architecture>x86_64</architecture>
90+
<rootDeviceType>ebs</rootDeviceType>
91+
<rootDeviceName>/dev/xvda</rootDeviceName>
92+
<blockDeviceMapping>
93+
<item>
94+
<deviceName>/dev/xvda</deviceName>
95+
<ebs>
96+
<volumeId>vol-08225e4fc2fde8e73</volumeId>
97+
<status>attached</status>
98+
<attachTime>2019-07-01T21:15:48.000Z</attachTime>
99+
<deleteOnTermination>true</deleteOnTermination>
100+
</ebs>
101+
</item>
102+
</blockDeviceMapping>
103+
<virtualizationType>hvm</virtualizationType>
104+
<clientToken/>
105+
<hypervisor>xen</hypervisor>
106+
<networkInterfaceSet>
107+
<item>
108+
<networkInterfaceId>eni-0ba368b59d3f5230e</networkInterfaceId>
109+
<subnetId>subnet-21959558</subnetId>
110+
<vpcId>vpc-1de55365</vpcId>
111+
<description/>
112+
<ownerId>183557167593</ownerId>
113+
<status>in-use</status>
114+
<macAddress>02:36:86:6e:84:7c</macAddress>
115+
<privateIpAddress>172.31.30.42</privateIpAddress>
116+
<privateDnsName>ip-172-31-30-42.us-west-2.compute.internal</privateDnsName>
117+
<sourceDestCheck>true</sourceDestCheck>
118+
<groupSet>
119+
<item>
120+
<groupId>sg-02d1f51eb2fa52795</groupId>
121+
<groupName>launch-wizard-2</groupName>
122+
</item>
123+
</groupSet>
124+
<attachment>
125+
<attachmentId>eni-attach-0d52b5e24dcb77ede</attachmentId>
126+
<deviceIndex>0</deviceIndex>
127+
<status>attached</status>
128+
<attachTime>2019-07-01T21:15:47.000Z</attachTime>
129+
<deleteOnTermination>true</deleteOnTermination>
130+
</attachment>
131+
<association>
132+
<publicIp>34.219.17.124</publicIp>
133+
<publicDnsName>ec2-34-219-17-124.us-west-2.compute.amazonaws.com</publicDnsName>
134+
<ipOwnerId>amazon</ipOwnerId>
135+
</association>
136+
<privateIpAddressesSet>
137+
<item>
138+
<privateIpAddress>172.31.30.42</privateIpAddress>
139+
<privateDnsName>ip-172-31-30-42.us-west-2.compute.internal</privateDnsName>
140+
<primary>true</primary>
141+
<association>
142+
<publicIp>34.219.17.124</publicIp>
143+
<publicDnsName>ec2-34-219-17-124.us-west-2.compute.amazonaws.com</publicDnsName>
144+
<ipOwnerId>amazon</ipOwnerId>
145+
</association>
146+
</item>
147+
</privateIpAddressesSet>
148+
<ipv6AddressesSet/>
149+
<interfaceType>interface</interfaceType>
150+
</item>
151+
</networkInterfaceSet>
152+
<ebsOptimized>false</ebsOptimized>
153+
<enaSupport>true</enaSupport>
154+
<cpuOptions>
155+
<coreCount>1</coreCount>
156+
<threadsPerCore>1</threadsPerCore>
157+
</cpuOptions>
158+
<capacityReservationSpecification>
159+
<capacityReservationPreference>open</capacityReservationPreference>
160+
</capacityReservationSpecification>
161+
<hibernationOptions>
162+
<configured>false</configured>
163+
</hibernationOptions>
164+
</item>
165+
</instancesSet>
166+
</item>
167+
</reservationSet>
168+
</DescribeInstancesResponse>`))
169+
req := aws.Request{Data: &ec2.DescribeInstancesOutput{}, HTTPResponse: &http.Response{Body: ioutil.NopCloser(buf)}}
170+
return &req
171+
}

0 commit comments

Comments
 (0)