Play Framework: Explain Performance
I tried to tweak the Java Framework Framework sample application (version 2.2.2) to test its performance against some simple use cases I had in mind. Here's what I did:
Play controller
I wrote a basic application controller to test the performance of a custom library that I wanted to use in both sync scripts and async:
public class Application extends Controller {
public static JsonNode transform(Request request) {
// this method reads a json from request, applies some transformation and returns a new JsonNode
}
public static Result syncTest() {
JsonNode node = transform(request());
if(node.has("error")) {
return badRequest(node);
} else {
return ok(node);
}
}
public static Promise<Result> asyncTest() {
final Request request = request();
Promise<JsonNode> promise = Promise.promise(
new Function0<JsonNode>() {
public JsonNode apply() {
return transform(request);
}
});
return promise.map(new Function<JsonNode, Result> () {
public Result apply(JsonNode node) {
if(node.has("error")) {
return badRequest(node);
} else {
return ok(node);
}
}
});
}
}
I am running this service in a VM running on Azure with 2 2.0ghz cores and 3.4GB of RAM.
Testing
I used wrk from another computer to run tests on both sync routes and async routes. These are the commands and results I got:
./wrk -s post.lua -d30s -c100 -t10 --latency http://my.proxy.net:8080/syncTest
Running 30s test @
10 threads and 100 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 84.98ms 48.13ms 410.73ms 68.95%
Req/Sec 121.23 18.90 181.00 73.67%
Latency Distribution
50% 81.36ms
75% 112.51ms
90% 144.44ms
99% 231.99ms
36362 requests in 30.03s, 10.99MB read
Requests/sec: 1210.80
Transfer/sec: 374.83KB
./wrk -s post.lua -d30s -c100 -t10 --latency http://my.proxy.net:8080/asyncTest
Running 30s test @
10 threads and 100 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 82.07ms 36.55ms 257.93ms 70.53%
Req/Sec 122.44 15.39 161.00 73.24%
Latency Distribution
50% 80.26ms
75% 102.37ms
90% 127.14ms
99% 187.17ms
36668 requests in 30.02s, 11.09MB read
Requests/sec: 1221.62
Transfer/sec: 378.18KB
./wrk -s post.lua -d30s -c1000 -t10 --latency http://my.proxy.net:8080/syncTest
Running 30s test @
10 threads and 1000 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 842.98ms 617.40ms 4.18s 59.56%
Req/Sec 118.02 16.82 174.00 77.50%
Latency Distribution
50% 837.67ms
75% 1.14s
90% 1.71s
99% 2.51s
35326 requests in 30.01s, 10.68MB read
Socket errors: connect 0, read 27, write 0, timeout 181
Requests/sec: 1176.97
Transfer/sec: 364.35KB
./wrk -s post.lua -d30s -c1000 -t10 --latency http://my.proxy.net:8080/asyncTest
Running 30s test @
10 threads and 1000 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 5.98s 4.53s 17.97s 72.66%
Req/Sec 21.32 10.45 37.00 59.74%
Latency Distribution
50% 4.86s
75% 8.30s
90% 12.89s
99% 17.10s
6361 requests in 30.08s, 1.92MB read
Socket errors: connect 0, read 0, write 0, timeout 8410
Requests/sec: 211.47
Transfer/sec: 65.46KB
During all tests, both processors on the server machine were running at 100%. Later, I repeated these experiments, but modified the Promises I created to run in a different execution context than the default. In this case, both synchronous and asynchronous methods are executed in a very similar way.
Questions
-
Why when using 10 threads with 100 connections, both methods have similar latency and request in seconds.
-
Why, when using 1000 connections, the asynchronous method has the worst performance, which is asynchronous or, in the case of a separate execution context, the same performance for the synchronization methods?
Is it because the conversion method is not really intensive because I did the wrong asynchronous implementation or because I didn't completely understand how this thing is supposed to work?
Thanks in advance!
source to share
No one has answered this question yet
Check out similar questions: