Skip to content

Commit

Permalink
Use Caliper for benchmarking.
Browse files Browse the repository at this point in the history
  • Loading branch information
squarejesse committed Feb 1, 2014
1 parent b52e041 commit 99841ae
Show file tree
Hide file tree
Showing 8 changed files with 111 additions and 42 deletions.
11 changes: 11 additions & 0 deletions benchmarks/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@
<name>Benchmarks</name>

<dependencies>
<dependency>
<groupId>com.google.caliper</groupId>
<artifactId>caliper</artifactId>
<version>1.0-beta-1</version>
</dependency>
<dependency>
<groupId>com.squareup.okhttp</groupId>
<artifactId>okhttp</artifactId>
Expand Down Expand Up @@ -51,5 +56,11 @@
<artifactId>netty-codec-http</artifactId>
<version>4.0.15.Final</version>
</dependency>
<!-- Netty needs this if gzip is enabled. -->
<dependency>
<groupId>com.jcraft</groupId>
<artifactId>jzlib</artifactId>
<version>1.1.2</version>
</dependency>
</dependencies>
</project>
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,6 @@ public ApacheHttpClientRequest(URL url) {
}

public void run() {
byte[] buffer = new byte[1024];
long start = System.nanoTime();
try {
HttpResponse response = client.execute(new HttpGet(url.toString()));
Expand All @@ -71,12 +70,7 @@ public void run() {
in = new GZIPInputStream(in);
}

// Consume the response body.
int total = 0;
for (int count; (count = in.read(buffer)) != -1; ) {
total += count;
}
in.close();
long total = readAllAndClose(in);
long finish = System.nanoTime();

if (VERBOSE) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@
*/
package com.squareup.okhttp.benchmarks;

import com.google.caliper.Param;
import com.google.caliper.model.ArbitraryMeasurement;
import com.google.caliper.runner.CaliperMain;
import com.squareup.okhttp.Protocol;
import com.squareup.okhttp.internal.SslContextBuilder;
import com.squareup.okhttp.mockwebserver.Dispatcher;
Expand All @@ -40,41 +43,57 @@
* It uses a local connection to a MockWebServer to measure how many identical
* requests per second can be carried over a fixed number of threads.
*/
public class Benchmark {
public class Benchmark extends com.google.caliper.Benchmark {
private static final int NUM_REPORTS = 10;
private static final boolean VERBOSE = false;

private final Random random = new Random(0);

/** Which client to run.*/
HttpClient httpClient = new NettyHttpClient();
@Param
Client client;

/** How many concurrent requests to execute. */
int concurrencyLevel = 10;
@Param({ "1", "10" })
int concurrencyLevel;

/** True to use TLS. */
// TODO: compare different ciphers?
boolean tls = false;
@Param
boolean tls;

/** True to use gzip content-encoding for the response body. */
boolean gzip = false;
@Param
boolean gzip;

/** Don't combine chunked with SPDY_3 or HTTP_2; that's not allowed. */
boolean chunked = false;
@Param
boolean chunked;

/** The size of the HTTP response body, in uncompressed bytes. */
int bodyByteCount = 1024 * 1024;
@Param({ "128", "1048576" })
int bodyByteCount;

/** How many additional headers were included, beyond the built-in ones. */
int headerCount = 20;
@Param({ "0", "20" })
int headerCount;

/** Which ALPN/NPN protocols are in use. Only useful with TLS. */
List<Protocol> protocols = Arrays.asList(Protocol.HTTP_11);

public static void main(String[] args) throws Exception {
new Benchmark().run();
public static void main(String[] args) {
List<String> allArgs = new ArrayList<String>();
allArgs.add("--instrument");
allArgs.add("arbitrary");
allArgs.addAll(Arrays.asList(args));

CaliperMain.main(Benchmark.class, allArgs.toArray(new String[allArgs.size()]));
}

public void run() throws Exception {
System.out.println(toString());
@ArbitraryMeasurement(description = "requests per second")
public double run() throws Exception {
if (VERBOSE) System.out.println(toString());
HttpClient httpClient = client.create();

// Prepare the client & server
httpClient.prepare(this);
Expand All @@ -85,6 +104,7 @@ public void run() throws Exception {
long reportStart = System.nanoTime();
long reportPeriod = TimeUnit.SECONDS.toNanos(1);
int reports = 0;
double best = 0.0;

// Run until we've printed enough reports.
while (reports < NUM_REPORTS) {
Expand All @@ -93,7 +113,10 @@ public void run() throws Exception {
double reportDuration = now - reportStart;
if (reportDuration > reportPeriod) {
double requestsPerSecond = requestCount / reportDuration * TimeUnit.SECONDS.toNanos(1);
System.out.println(String.format("Requests per second: %.1f", requestsPerSecond));
if (VERBOSE) {
System.out.println(String.format("Requests per second: %.1f", requestsPerSecond));
}
best = Math.max(best, requestsPerSecond);
requestCount = 0;
reportStart = now;
reports++;
Expand All @@ -108,6 +131,8 @@ public void run() throws Exception {
// The job queue is full. Take a break.
sleep(10);
}

return best;
}

@Override public String toString() {
Expand All @@ -117,10 +142,8 @@ public void run() throws Exception {
if (chunked) modifiers.add("chunked");
modifiers.addAll(protocols);

return String.format("%s %s\n"
+ "bodyByteCount=%s headerCount=%s concurrencyLevel=%s",
httpClient.getClass().getSimpleName(), modifiers,
bodyByteCount, headerCount, concurrencyLevel);
return String.format("%s %s\nbodyByteCount=%s headerCount=%s concurrencyLevel=%s",
client, modifiers, bodyByteCount, headerCount, concurrencyLevel);
}

private void sleep(int millis) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*
* Copyright (C) 2014 Square, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.squareup.okhttp.benchmarks;

enum Client {
OkHttp {
@Override HttpClient create() {
return new OkHttp();
}
},

Apache {
@Override HttpClient create() {
return new ApacheHttpClient();
}
},

UrlConnection {
@Override HttpClient create() {
return new UrlConnection();
}
},

Netty {
@Override HttpClient create() {
return new NettyHttpClient();
}
};

abstract HttpClient create();
}
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@
import javax.net.ssl.SSLEngine;

/** Netty isn't an HTTP client, but it's almost one. */
public class NettyHttpClient implements HttpClient {
class NettyHttpClient implements HttpClient {
private static final boolean VERBOSE = false;

// Guarded by this. Real apps need more capable connection management.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
import com.squareup.okhttp.OkHttpClient;
import com.squareup.okhttp.internal.SslContextBuilder;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.concurrent.TimeUnit;
Expand Down Expand Up @@ -62,18 +61,10 @@ public OkHttpRequest(URL url) {
}

public void run() {
byte[] buffer = new byte[1024];
long start = System.nanoTime();
try {
HttpURLConnection urlConnection = client.open(url);
InputStream in = urlConnection.getInputStream();

// Consume the response body.
int total = 0;
for (int count; (count = in.read(buffer)) != -1; ) {
total += count;
}
in.close();
long total = readAllAndClose(urlConnection.getInputStream());
long finish = System.nanoTime();

if (VERBOSE) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
*/
package com.squareup.okhttp.benchmarks;

import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
Expand All @@ -38,5 +40,15 @@ abstract class SynchronousHttpClient implements HttpClient {
return executor.getQueue().size() < targetBacklog;
}

protected long readAllAndClose(InputStream in) throws IOException {
byte[] buffer = new byte[1024];
long total = 0;
for (int count; (count = in.read(buffer)) != -1; ) {
total += count;
}
in.close();
return total;
}

abstract Runnable request(URL url);
}
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,6 @@ public UrlConnectionRequest(URL url) {
}

public void run() {
byte[] buffer = new byte[1024];
long start = System.nanoTime();
try {
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
Expand All @@ -67,12 +66,7 @@ public void run() {
in = new GZIPInputStream(in);
}

// Consume the response body.
int total = 0;
for (int count; (count = in.read(buffer)) != -1; ) {
total += count;
}
in.close();
long total = readAllAndClose(in);
long finish = System.nanoTime();

if (VERBOSE) {
Expand Down

0 comments on commit 99841ae

Please sign in to comment.