Skip to content

Commit

Permalink
consolidated RPC benchmarks into one, basic framework for gRPC and RE…
Browse files Browse the repository at this point in the history
…STful JSON API done.
  • Loading branch information
david-cao committed Jul 6, 2016
1 parent c7207d2 commit 87d2bda
Show file tree
Hide file tree
Showing 23 changed files with 650 additions and 553 deletions.
4 changes: 3 additions & 1 deletion gRPCBenchmarks/app/build.gradle
Expand Up @@ -5,6 +5,9 @@ android {
compileSdkVersion 23
buildToolsVersion "23.0.3"

// This is for metrics, no workaround for now?
// useLibrary 'org.apache.http.legacy'

sourceSets {
main {
proto {
Expand Down Expand Up @@ -61,7 +64,6 @@ protobuf {
task.plugins {
grpc {
// Options added to --grpc_out
// TODO: make project lite compatible
option 'lite'
}
}
Expand Down
7 changes: 5 additions & 2 deletions gRPCBenchmarks/app/src/main/AndroidManifest.xml
Expand Up @@ -27,8 +27,11 @@
android:name=".GrpcBenchmarksActivity"
android:label="@string/grpcBenchmarksName">
</activity>
<activity android:name=".JsonBenchmarkActivity"
android:label="@string/jsonBenchmarksName">
<activity
android:name=".JsonBenchmarkActivity"
android:label="@string/jsonBenchmarksName">
</activity>
<activity android:name=".RpcBenchmarksActivity">
</activity>
</application>

Expand Down
Expand Up @@ -22,7 +22,7 @@ public BenchmarkResult(String name, int iters, long elapsed, float mbps, long si

@Override
public String toString() {
return name + ": serialized size: " + size + "bytes"
return "Serialized size: " + size + "bytes"
+ (compressedSize != 0 ? " (" + compressedSize + "bytes gzipped), " : ", ")
+ iterations + " iterations in " + (elapsed / 1000f)
+ "s, ~" + mbps + "Mb/s.";
Expand Down
Expand Up @@ -2,6 +2,7 @@

import android.content.Context;
import android.os.AsyncTask;
import android.os.Build;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.text.TextUtils;
Expand All @@ -11,6 +12,8 @@
import android.widget.EditText;
import android.widget.TextView;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.concurrent.TimeUnit;

import io.grpc.ManagedChannel;
Expand Down Expand Up @@ -69,14 +72,36 @@ public void beginBenchmark(View v) {
String host = mHostEdit.getText().toString();
String port = mPortEdit.getText().toString();
String addr = "--address=" + host + ":" + port;
testPing(host);

mBenchmarkButton.setEnabled(false);

new BenchmarkTask().execute(addr);
// We don't want benchmarks to run in parallel, so make sure they are in serial order
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
new BenchmarkTask().executeOnExecutor(AsyncTask.SERIAL_EXECUTOR, addr,
"--channels=1", "--outstanding_rpcs=1", "--client_payload=100",
"--server_payload=100", "--streaming_rpcs");
} else {
new BenchmarkTask().execute(addr, "--channels=1", "--outstanding_rpcs=1",
"--client_payload=100", "--server_payload=100", "--streaming_rpcs");
}
}

private class BenchmarkTask extends AsyncTask<String, Void, String> {
public void testPing(String host) {
try {
Process p = Runtime.getRuntime().exec(new String[]{"ping", "-c", "4", host});
BufferedReader stdInput = new BufferedReader(new InputStreamReader(p.getInputStream()));

String s;
while ((s = stdInput.readLine()) != null) {
System.out.println(s);
}
} catch (Exception e) {
System.out.println("failed to ping");
}
}

private class BenchmarkTask extends AsyncTask<String, Void, String> {
@Override
protected void onPreExecute() {
System.out.println("Starting gRPC benchmarks");
Expand All @@ -94,10 +119,10 @@ protected String doInBackground(String... args) {
ClientConfiguration config;
config = configBuilder.build(args);
AsyncClient client = new AsyncClient(config);
GrpcBenchmarkResult grpcBenchmarkResult = client.run();
RpcBenchmarkResult grpcBenchmarkResult = client.run();
results += grpcBenchmarkResult.toString();
} catch (Exception e) {
System.out.println("Benchmarking error: " + e.getMessage());
System.out.println("Benchmarking error: " + e);
configBuilder.printUsage();
}

Expand Down
Expand Up @@ -13,13 +13,8 @@ protected void onCreate(Bundle savedInstanceState) {
setContentView(R.layout.activity_home);
}

public void showProtobufBenchmarks(View v) {
Intent intent = new Intent(this, ProtobufBenchmarksActivity.class);
startActivity(intent);
}

public void showGrpcBenchmarks(View v) {
Intent intent = new Intent(this, GrpcBenchmarksActivity.class);
public void showRpcBenchmarks(View v) {
Intent intent = new Intent(this, RpcBenchmarksActivity.class);
startActivity(intent);
}

Expand Down
@@ -1,20 +1,14 @@
package io.grpc.grpcbenchmarks;

import android.os.AsyncTask;
import android.os.Build;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

import org.apache.commons.io.IOUtils;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;

import io.grpc.grpcbenchmarks.qps.AsyncJsonClient;
Expand All @@ -39,66 +33,57 @@ protected void onCreate(Bundle savedInstanceState) {
}

public void sendMessage(View v) {
String host = mHostEdit.getText().toString();
String port = mPortEdit.getText().toString();
new CallAPI().execute("http://" + host + ":" + port + "/postPayload", "TEST");
// String host = mHostEdit.getText().toString();
// String port = mPortEdit.getText().toString();
// String urlString = "http://" + host + ":" + port + "/postPayload";
// try {
// AsyncJsonClient jsonClient = new AsyncJsonClient(new URL(urlString));
// jsonClient.run();
// } catch (Exception e) {
// System.out.println("Exception! " + e);
// }
}

public void beginBenchmark(View v) {
String host = mHostEdit.getText().toString();
String port = mPortEdit.getText().toString();
String urlString = "http://" + host + ":" + port + "/postPayload";

// We don't want benchmarks to run in parallel, so make sure they are in serial order
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
new CallAPI().executeOnExecutor(AsyncTask.SERIAL_EXECUTOR, urlString);
} else {
new CallAPI().execute(urlString);
}
}

private class CallAPI extends AsyncTask<String, Void, String> {

public CallAPI() {
@Override
public void onPreExecute() {
mBenchmarkButton.setEnabled(false);
}

// Format should be url, payload, other params
@Override
protected String doInBackground(String... params) {
String urlString = params[0];
try {
AsyncJsonClient jsonClient = new AsyncJsonClient(new URL(urlString));
jsonClient.run();
} catch (Exception e) {
System.out.println("Exception! " + e);
} finally {
return null;
}

// byte payload[] = params[1].getBytes();
//
// InputStream in;
// String result = "";
// String urlString = params[0];
// try {
// URL url = new URL(urlString);
//
// HttpURLConnection connection = (HttpURLConnection) url.openConnection();
// connection.setDoOutput(true);
//// connection.setChunkedStreamingMode(0);
// connection.setFixedLengthStreamingMode(payload.length);
//
// OutputStream out = new BufferedOutputStream(connection.getOutputStream());
// out.write(payload);
// out.close();
//
// in = new BufferedInputStream(connection.getInputStream());
//
// String response = IOUtils.toString(in);
// System.out.println("Reponse: " + response);
//
// connection.disconnect();
//
// return response;
// AsyncJsonClient jsonClient = new AsyncJsonClient(new URL(urlString));
// RpcBenchmarkResult res = jsonClient.run();
// result = res.toString();
// } catch (Exception e) {
// System.out.println("Connection error: " + e);
// return "Error";
// System.out.println("Exception! " + e);
// } finally {
// return result;
// }
return "blah";
}

@Override
protected void onPostExecute(String res) {
mBenchmarkButton.setEnabled(true);
mResultText.setText(res);
}
}

}
Expand Up @@ -3,6 +3,7 @@
import com.google.protobuf.MessageLite;

import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
Expand Down Expand Up @@ -81,14 +82,14 @@ public void onClick(View v) {

private void initializeBenchmarks() {
benchmarks = new ArrayList<>();
benchmarks.add(new Benchmark("Serialize protobuf to byte array", "description", 0));
benchmarks.add(new Benchmark("Serialize protobuf to CodedOutputStream", "description", 1));
benchmarks.add(new Benchmark("Serialize protobuf to ByteArrayOutputStream", "description", 2));
benchmarks.add(new Benchmark("Deserialize protobuf from byte array", "description", 3));
benchmarks.add(new Benchmark("Deserialize protobuf from CodedInputStream", "description", 4));
benchmarks.add(new Benchmark("Deserialize protobuf from ByteArrayInputStream", "description", 5));
benchmarks.add(new Benchmark("Serialize JSON to byte array", "description", 6));
benchmarks.add(new Benchmark("Deserialize JSON from byte array", "description", 7));
benchmarks.add(new Benchmark("Serialize protobuf to byte array", "", 0));
benchmarks.add(new Benchmark("Serialize protobuf to CodedOutputStream", "", 1));
benchmarks.add(new Benchmark("Serialize protobuf to ByteArrayOutputStream", "", 2));
benchmarks.add(new Benchmark("Deserialize protobuf from byte array", "", 3));
benchmarks.add(new Benchmark("Deserialize protobuf from CodedInputStream", "", 4));
benchmarks.add(new Benchmark("Deserialize protobuf from ByteArrayInputStream", "", 5));
benchmarks.add(new Benchmark("Serialize JSON to byte array", "", 6));
benchmarks.add(new Benchmark("Deserialize JSON from byte array", "", 7));
}

public void beginAllBenchmarks(View v) {
Expand Down Expand Up @@ -135,7 +136,11 @@ public void beginAllBenchmarks(View v) {

public void startBenchmark(CardView cv, Benchmark b) {
BenchmarkAsyncTask task = new BenchmarkAsyncTask(cv, b);
task.execute();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
task.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR);
} else {
task.execute();
}
}

//BEGIN OnItemSelectedListener
Expand Down
Expand Up @@ -249,7 +249,6 @@ public static MessageLite randomProto2(Random r) {
return friendsListBuilder.build();
}

// TODO: maybe find a way to trim this down...
public static MessageLite randomProto3(int stringSize, boolean fixed) {
Random r = new Random();
return randomProto3(r, stringSize, fixed);
Expand Down
@@ -0,0 +1,64 @@
package io.grpc.grpcbenchmarks;

import java.net.URL;

import io.grpc.grpcbenchmarks.qps.AsyncClient;
import io.grpc.grpcbenchmarks.qps.AsyncJsonClient;
import io.grpc.grpcbenchmarks.qps.ClientConfiguration;

import static io.grpc.grpcbenchmarks.qps.ClientConfiguration.ClientParam.ADDRESS;
import static io.grpc.grpcbenchmarks.qps.ClientConfiguration.ClientParam.CHANNELS;
import static io.grpc.grpcbenchmarks.qps.ClientConfiguration.ClientParam.CLIENT_PAYLOAD;
import static io.grpc.grpcbenchmarks.qps.ClientConfiguration.ClientParam.DIRECTEXECUTOR;
import static io.grpc.grpcbenchmarks.qps.ClientConfiguration.ClientParam.DURATION;
import static io.grpc.grpcbenchmarks.qps.ClientConfiguration.ClientParam.OUTSTANDING_RPCS;
import static io.grpc.grpcbenchmarks.qps.ClientConfiguration.ClientParam.SAVE_HISTOGRAM;
import static io.grpc.grpcbenchmarks.qps.ClientConfiguration.ClientParam.SERVER_PAYLOAD;
import static io.grpc.grpcbenchmarks.qps.ClientConfiguration.ClientParam.STREAMING_RPCS;
import static io.grpc.grpcbenchmarks.qps.ClientConfiguration.ClientParam.TESTCA;
import static io.grpc.grpcbenchmarks.qps.ClientConfiguration.ClientParam.TLS;
import static io.grpc.grpcbenchmarks.qps.ClientConfiguration.ClientParam.TRANSPORT;
import static io.grpc.grpcbenchmarks.qps.ClientConfiguration.ClientParam.USE_DEFAULT_CIPHERS;
import static io.grpc.grpcbenchmarks.qps.ClientConfiguration.ClientParam.WARMUP_DURATION;

/**
* Created by davidcao on 6/30/16.
*/
public class RpcBenchmark {

String title;
String description;
int methodNumber;

public RpcBenchmark(String title, String description, int methodNumber) {
this.title = title;
this.description = description;
this.methodNumber = methodNumber;
}

public RpcBenchmarkResult run(String urlString, String numConnections) throws Exception {
switch (methodNumber) {
// TODO: Allow for customization!
case 0:
String addr = "--address=" + urlString + ":50052";
String[] args = {addr, "--channels=1", "--outstanding_rpcs=" + numConnections,
"--client_payload=100", "--server_payload=100"};
ClientConfiguration.Builder configBuilder = ClientConfiguration.newBuilder(
ADDRESS, CHANNELS, OUTSTANDING_RPCS, CLIENT_PAYLOAD, SERVER_PAYLOAD,
TLS, TESTCA, USE_DEFAULT_CIPHERS, TRANSPORT, DURATION, WARMUP_DURATION,
DIRECTEXECUTOR, SAVE_HISTOGRAM, STREAMING_RPCS);
ClientConfiguration config;
config = configBuilder.build(args);
AsyncClient client = new AsyncClient(config);
return client.run();
case 1:
int outstandingConnections = Integer.parseInt(numConnections);
AsyncJsonClient jsonClient = new AsyncJsonClient(new URL("http://" + urlString +
":4567/postPayload"), outstandingConnections);
return jsonClient.run();
default:
throw new IllegalArgumentException("Invalid method number/tag was" +
" used for RpcBenchmark!");
}
}
}

0 comments on commit 87d2bda

Please sign in to comment.