RAP 3.0 Boosts Performance

RAP 3.0 Boosts Performance

This week, the third major version of RAP, the Eclipse Remote Application Platform, has been released. As a major release, RAP 3.0 cleaned up deprecated API, allowing us to change and to optimize internals. I’m happy to report that we achieved a significant performance boost compared to 2.3. Before I go into details, let’s look at some results.

Performance Tests

To evaluate the performance of RAP 3.0, we created a new load test setup. We deployed a test application with more than 300 widgets on an average cloud server (4 CPUs @2.80GHz and 8GB of memory). On another machine, we ramped up 1000 parallel user sessions, each issuing requests at a rate of one per second. The requests themselves are small, containing an event and some updated properties. Here’s the results of a test run with RAP 2.3.2:

RAP 2.3

Shortly before reaching 1000 requests per second the system started to degrade in response times, but stabilized at a level of ~60 ms. The server CPU utilization during this time was ~90%.

Running the exact same scenario with RAP 3.0, we saw an average server load of ~65% and the response times have dropped significantly:

RAP 3.0

With an average response time below 10 ms and 99% of all requests finishing in less than 100 ms, this is a result we are very happy with.

Response Times

Test Setup

We used Gatling, a powerful load test tool that creates nice and meaningful reports. I’ve aligned the scales of both graphs to make them easier to compare. The test application and test scenarios are all public, allowing you to reproduce and to adapt the tests to your needs.

The application ran on the latest Oracle Java 8 VM using the G1 garbage collector (-server -XX:+UseG1GC).

Background: Change Detection

Various changes contributed to the performance boost in RAP 3.0. For example, the synchronization in the RWT servlet has been reworked. Initial GET requests don’t create a separate UISession anymore. However, the biggest performance gain was achieved by a number of improvements to the change detection. This mechanism preserves the current UI state before processing a request and then compares it with the state afterwards in order to detect and render changes.

Due to the remote processing model of RAP, clients can send requests to the server at a high rate, for example, when typing in a text field with a server-side listener for validation or data binding. Many of these requests have only little effect on the UI. However, since the change detection has the same amount of work to do for every request, it contributes significantly to the server load in these cases.

To speed up this process, most standard Control properties such as bounds or font, are now preserved in dedicated fields in a new, optimized data structure instead of HashMap entries. For example, information about all attached listeners are now kept as a bitmask in a single long value. We also reduced the number of short living objects created during the change detection in order to reduce GC load.

During this work, some more ideas came up and I’m looking forward to further improving the performance of RAP. Big thanks go out to the nice guys at MIC, who contributed their insights and sponsored the performance work in RAP 3.0.