• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2010 The Android Open Source Project
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  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package benchmarks.regression;
18 
19 import com.google.caliper.Param;
20 import com.google.mockwebserver.Dispatcher;
21 import com.google.mockwebserver.MockResponse;
22 import com.google.mockwebserver.MockWebServer;
23 import com.google.mockwebserver.RecordedRequest;
24 import java.io.IOException;
25 import java.io.InputStream;
26 import java.net.HttpURLConnection;
27 import java.net.URL;
28 
29 public final class URLConnectionBenchmark {
30 
31     @Param({"0", "1024", "1048576"}) private int bodySize;
32     @Param({"2048"}) private int chunkSize;
33     @Param({"1024"}) private int readBufferSize;
34     @Param private ResponseHeaders responseHeaders;
35     @Param private TransferEncoding transferEncoding;
36     private byte[] readBuffer;
37 
38     private MockWebServer server;
39     private URL url;
40 
41     private static class SingleResponseDispatcher extends Dispatcher {
42         private MockResponse response;
SingleResponseDispatcher(MockResponse response)43         SingleResponseDispatcher(MockResponse response) {
44             this.response = response;
45         }
dispatch(RecordedRequest request)46         @Override public MockResponse dispatch(RecordedRequest request) {
47             return response;
48         }
49     };
50 
setUp()51     protected void setUp() throws Exception {
52         readBuffer = new byte[readBufferSize];
53         server = new MockWebServer();
54 
55         MockResponse response = new MockResponse();
56         responseHeaders.apply(response);
57         transferEncoding.setBody(response, bodySize, chunkSize);
58 
59         // keep serving the same response for all iterations
60         server.setDispatcher(new SingleResponseDispatcher(response));
61         server.play();
62 
63         url = server.getUrl("/");
64         get(); // ensure the server has started its threads, etc.
65     }
66 
tearDown()67     protected void tearDown() throws Exception {
68         server.shutdown();
69     }
70 
timeGet(int reps)71     public int timeGet(int reps) throws IOException {
72         int totalBytesRead = 0;
73         for (int i = 0; i < reps; i++) {
74             totalBytesRead += get();
75         }
76         return totalBytesRead;
77     }
78 
get()79     private int get() throws IOException {
80         int totalBytesRead = 0;
81         HttpURLConnection connection = (HttpURLConnection) url.openConnection();
82         // URLConnection connection = url.openConnection();
83         InputStream in = connection.getInputStream();
84         int count;
85         while ((count = in.read(readBuffer)) != -1) {
86             totalBytesRead += count;
87         }
88         return totalBytesRead;
89     }
90 
91     enum TransferEncoding {
92         FIXED_LENGTH,
93         CHUNKED;
94 
setBody(MockResponse response, int bodySize, int chunkSize)95         void setBody(MockResponse response, int bodySize, int chunkSize) throws IOException {
96             if (this == TransferEncoding.FIXED_LENGTH) {
97                 response.setBody(new byte[bodySize]);
98             } else if (this == TransferEncoding.CHUNKED) {
99                 response.setChunkedBody(new byte[bodySize], chunkSize);
100             }
101         }
102     }
103 
104     enum ResponseHeaders {
105         MINIMAL,
106         TYPICAL;
107 
apply(MockResponse response)108         void apply(MockResponse response) {
109             if (this == TYPICAL) {
110                 /* from http://api.twitter.com/1/statuses/public_timeline.json */
111                 response.addHeader("Date: Wed, 30 Jun 2010 17:57:39 GMT");
112                 response.addHeader("Server: hi");
113                 response.addHeader("X-RateLimit-Remaining: 0");
114                 response.addHeader("X-Runtime: 0.01637");
115                 response.addHeader("Content-Type: application/json; charset=utf-8");
116                 response.addHeader("X-RateLimit-Class: api_whitelisted");
117                 response.addHeader("Cache-Control: no-cache, max-age=300");
118                 response.addHeader("X-RateLimit-Reset: 1277920980");
119                 response.addHeader("Set-Cookie: _twitter_sess=BAh7EDoOcmV0dXJuX3RvIjZodHRwOi8vZGV2L"
120                         + "nR3aXR0ZXIuY29tL3BhZ2Vz%250AL3NpZ25faW5fd2l0aF90d2l0dGVyOgxjc3JmX2lkIiUw"
121                         + "ODFhNGY2NTM5NjRm%250ANjY1N2M2NzcwNWI0MDlmZGZjZjoVaW5fbmV3X3VzZXJfZmxvdzA"
122                         + "6EXRyYW5z%250AX3Byb21wdDAiKXNob3dfZGlzY292ZXJhYmlsaXR5X2Zvcl9qZXNzZXdpbH"
123                         + "Nv%250AbjA6E3Nob3dfaGVscF9saW5rMDoTcGFzc3dvcmRfdG9rZW4iLWUyYjlhNmM3%250A"
124                         + "MWJiNzI3NWNlZDI1NDY3MGMzZWNmMTE0MjI4N2EyNGE6D2NyZWF0ZWRfYXRs%250AKwhiM%2"
125                         + "52F6JKQE6CXVzZXJpA8tE3iIKZmxhc2hJQzonQWN0aW9uQ29udHJvbGxl%250Acjo6Rmxhc2"
126                         + "g6OkZsYXNoSGFzaHsABjoKQHVzZWR7ADoHaWQiJWZmMTNhM2Qx%250AZTU1YTkzMmYyMWM0M"
127                         + "GNhZjU4NDVjMTQz--11250628c85830219438eb7eba96a541a9af4098; domain=.twitt"
128                         + "er.com; path=/");
129                 response.addHeader("Expires: Wed, 30 Jun 2010 18:02:39 GMT");
130                 response.addHeader("Vary: Accept-Encoding");
131             }
132         }
133     }
134 }
135