Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New benchmark target for Netty. #501

Merged
merged 1 commit into from
Feb 1, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions benchmarks/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -36,5 +36,20 @@
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
</dependency>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-transport</artifactId>
<version>4.0.15.Final</version>
</dependency>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-handler</artifactId>
<version>4.0.15.Final</version>
</dependency>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-codec-http</artifactId>
<version>4.0.15.Final</version>
</dependency>
</dependencies>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
/*
* 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;

import com.squareup.okhttp.internal.SslContextBuilder;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.concurrent.TimeUnit;
import java.util.zip.GZIPInputStream;
import javax.net.ssl.SSLContext;
import org.apache.http.Header;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.PoolingClientConnectionManager;

/** Benchmark Apache HTTP client. */
class ApacheHttpClient extends SynchronousHttpClient {
private static final boolean VERBOSE = false;

private HttpClient client;

@Override public void prepare(Benchmark benchmark) {
super.prepare(benchmark);
ClientConnectionManager connectionManager = new PoolingClientConnectionManager();
if (benchmark.tls) {
SSLContext sslContext = SslContextBuilder.localhost();
connectionManager.getSchemeRegistry().register(
new Scheme("https", 443, new SSLSocketFactory(sslContext)));
}
client = new DefaultHttpClient(connectionManager);
}

@Override public Runnable request(URL url) {
return new ApacheHttpClientRequest(url);
}

class ApacheHttpClientRequest implements Runnable {
private final URL url;

public ApacheHttpClientRequest(URL url) {
this.url = url;
}

public void run() {
byte[] buffer = new byte[1024];
long start = System.nanoTime();
try {
HttpResponse response = client.execute(new HttpGet(url.toString()));
InputStream in = response.getEntity().getContent();
Header contentEncoding = response.getFirstHeader("Content-Encoding");
if (contentEncoding != null && contentEncoding.getValue().equals("gzip")) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yek. (not saying there's a better way)

in = new GZIPInputStream(in);
}

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

if (VERBOSE) {
System.out.println(String.format("Transferred % 8d bytes in %4d ms",
total, TimeUnit.NANOSECONDS.toMillis(finish - start)));
}
} catch (IOException e) {
System.out.println("Failed: " + e);
}
}
}
}

This file was deleted.

109 changes: 13 additions & 96 deletions benchmarks/src/main/java/com/squareup/okhttp/benchmarks/Benchmark.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,36 +15,25 @@
*/
package com.squareup.okhttp.benchmarks;

import com.squareup.okhttp.OkHttpClient;
import com.squareup.okhttp.Protocol;
import com.squareup.okhttp.internal.SslContextBuilder;
import com.squareup.okhttp.internal.http.HttpsURLConnectionImpl;
import com.squareup.okhttp.mockwebserver.Dispatcher;
import com.squareup.okhttp.mockwebserver.MockResponse;
import com.squareup.okhttp.mockwebserver.MockWebServer;
import com.squareup.okhttp.mockwebserver.RecordedRequest;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Random;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.zip.GZIPOutputStream;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocketFactory;
import org.apache.http.client.HttpClient;
import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.PoolingClientConnectionManager;

/**
* This benchmark is fake, but may be useful for certain relative comparisons.
Expand All @@ -56,10 +45,10 @@ public class Benchmark {
private final Random random = new Random(0);

/** Which client to run.*/
Candidate candidate = new UrlConnection(); // new OkHttp(); // new ApacheHttpClient();
HttpClient httpClient = new NettyHttpClient();

/** How many concurrent threads to execute. */
int threadCount = 10;
/** How many concurrent requests to execute. */
int concurrencyLevel = 10;

/** True to use TLS. */
// TODO: compare different ciphers?
Expand All @@ -80,22 +69,18 @@ public class Benchmark {
/** 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 IOException {
public static void main(String[] args) throws Exception {
new Benchmark().run();
}

public void run() throws IOException {
ThreadPoolExecutor executor = new ThreadPoolExecutor(threadCount, threadCount,
1, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>());

public void run() throws Exception {
System.out.println(toString());

// Prepare the client & server
candidate.prepare();
httpClient.prepare(this);
MockWebServer server = startServer();
String url = server.getUrl("/").toString();
URL url = server.getUrl("/");

int targetBacklog = 10;
int requestCount = 0;
long reportStart = System.nanoTime();
long reportPeriod = TimeUnit.SECONDS.toNanos(1);
Expand All @@ -115,8 +100,8 @@ public void run() throws IOException {
}

// Fill the job queue with work.
while (executor.getQueue().size() < targetBacklog) {
executor.execute(candidate.request(url));
while (httpClient.acceptingJobs()) {
httpClient.enqueue(url);
requestCount++;
}

Expand All @@ -133,9 +118,9 @@ public void run() throws IOException {
modifiers.addAll(protocols);

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

private void sleep(int millis) {
Expand Down Expand Up @@ -207,72 +192,4 @@ private byte[] gzip(byte[] bytes) throws IOException {
gzippedOut.close();
return bytesOut.toByteArray();
}

interface Candidate {
void prepare();
Runnable request(String url);
}

class OkHttp implements Candidate {
private OkHttpClient client;

@Override public void prepare() {
client = new OkHttpClient();
client.setProtocols(protocols);

if (tls) {
SSLContext sslContext = SslContextBuilder.localhost();
SSLSocketFactory socketFactory = sslContext.getSocketFactory();
HostnameVerifier hostnameVerifier = new HostnameVerifier() {
@Override public boolean verify(String s, SSLSession session) {
return true;
}
};
client.setSslSocketFactory(socketFactory);
client.setHostnameVerifier(hostnameVerifier);
}
}

@Override public Runnable request(String url) {
return new OkHttpRequest(client, url);
}
}

class UrlConnection implements Candidate {
@Override public void prepare() {
if (tls) {
SSLContext sslContext = SslContextBuilder.localhost();
SSLSocketFactory socketFactory = sslContext.getSocketFactory();
HostnameVerifier hostnameVerifier = new HostnameVerifier() {
@Override public boolean verify(String s, SSLSession session) {
return true;
}
};
HttpsURLConnectionImpl.setDefaultHostnameVerifier(hostnameVerifier);
HttpsURLConnectionImpl.setDefaultSSLSocketFactory(socketFactory);
}
}

@Override public Runnable request(String url) {
return new UrlConnectionRequest(url);
}
}

class ApacheHttpClient implements Candidate {
private HttpClient client;

@Override public void prepare() {
ClientConnectionManager connectionManager = new PoolingClientConnectionManager();
if (tls) {
SSLContext sslContext = SslContextBuilder.localhost();
connectionManager.getSchemeRegistry().register(
new Scheme("https", 443, new org.apache.http.conn.ssl.SSLSocketFactory(sslContext)));
}
client = new DefaultHttpClient(connectionManager);
}

@Override public Runnable request(String url) {
return new ApacheHttpClientRequest(url, client);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/*
* 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;

import java.net.URL;

/** An HTTP client to benchmark. */
interface HttpClient {
void prepare(Benchmark benchmark);
void enqueue(URL url) throws Exception;
boolean acceptingJobs();
}
Loading