Bad GWT Request Factory performance for list of objects
Asked Answered
T

1

25

I am transferring a list of objects to the client with GWT Request Factory. The objects contain only a couple of strings and the list does only contain 20 objects. To transfer this small list of data, it takes over a second. First I thought the query needs to be optimised. But the measurement shows:

The retrieval of the objects from the database only takes

300ms

The transfer to the client takes in total over a second

1136ms

So this seems to be request factory overhead. I already use my own ServiceLayerDecorator and have overridden the isLive() function so it always return true. Are there any other actions I can take to speed this up and bring the performance to an acceptable area?

Update:

I created the logic to copy my entity object data to DTO and transfered them with RPC to compare the RPC and Request factory peformance. As you can see the RPC logic is much faster. Now I am wondering if that is by design or if there is a flaw in my application.

20 transfered objects:

Request factory: 1252 ms

RPC: 420 ms

28 transfered objects:

Request factory: 1654 ms

RPC: 460 ms

78 transfered objects:

Request factory: 3963 ms

RPC: 769 ms

============================================================

Update2

So I wrote a very simple sample application to make sure my application does not have any filters or other interfering components. The applications loads 10 objects with 4 String fields from the server. I did it with Request factory as well as RPC and stopped the time.

The code can be found here: https://github.com/jan10101/requstFactoryVSRPC

A life demo here: http://requestfactorytest.appspot.com/

The test application confirms my observation: The request factory performance is really bad compared to the RPC performance. In dev mode the performance of RPC is about 40 times better, in production mode still 4 times. Am I the first one noticing the performance issues?

The following screenshots show the test results if you don't want to try it yourself.

Results in dev mode:

enter image description here

Results of productive code (on app engine): enter image description here

Tortola answered 15/8, 2014 at 11:42 Comment(16)
How big are the 20 objects in terms of kilobytes? Do you get the same slow performance if you request the same data via a servlet bypassing the GWT request factory?Pyrrha
How are you measuring the time taken to transfer to the client? Are you measuring this using the browser? Is this in development mode?Daina
@pauli: I measure it directly in the code - Taking the time before firing the request and stopping the time in the onSuccess() method of the request. I tested in dev mode - I know that the app is slower in development mode, but in production code the request is slow as well.Tortola
The time could be down to time taken to perform the request in the server side application code, time taken serialising Java to JSON, transferring the data to the browser or time taken to deserialise from JSON to javascript. Or a combination. If there are lots of objects the deserialisation can sometimes be slow (try sending a large byte array across). All I can suggest is to try and time at various points in the request processing on the server.Daina
Could you name some place where I could measure? I already tried to debug and measure I but could not really figure out which parts are involved in the background for serializing and what else is happening under the hood.Tortola
So many ways... Server side RequestFactoryServlet is the entry point to handling the request. You could set the java system property gwt.rpc.dumpPayload to true. Depending on your server logging this may include timestamps. Or override the RequestFactoryServlet.doPost(...) method. On the client side it is possible to intercept the response by overriding the DefaultRequestTransport used by your RequestFactory class and see the responses as text before they are deserialised into javascript objects (or Java objects in dev mode). See stackoverflow.com/questions/7608235Daina
I found out at leas one thing RequestFactoryServlet.doPost() takes up 1s of the 4s total for the 78 object request. So at least it seam there is no single point takes up a lot of time...Tortola
That makes it sound like you either have another filter which is killing you, or something about however you get data from client to server (a proxy gone wrong?).Braille
I created a simple test application comparing RPC and request factory and it shows the same result. Request factory seems to be really slow. I updated the initial post with links to the code and a life demo.Tortola
You should profile the backend in more detail to see where it spends most time. But RequestFactory makes use of reflection (#12978422) to populate the Proxys and this will probably take more time than wtih RPC.Hedron
Added some timing measurement code to your test app by overriding the service(...) method of the RF and RPC servlets. My values are RPC: 3ms measured by server, 20ms measured by client. For RF: 65ms on server, 320ms on client. The discrepancy between values measured by client and server are due to transmission (probably negligible) and deserialisation by the client. So 17ms to deserialise RPC and 240ms to deserialise RF. (This was dev mode in FF20).Daina
@pauli: So you would agree that RF is slow as hell compared to RPC caused by serialization/deserialization overhead? And there is probably no way for significant improvments?Tortola
@pauli can you benchmark in production mode ?Hedron
I've forked the test app (github.com/pillingworthz/requstFactoryVSRPC) and added some more RF timings. In prod mode, RF server side starts at 300ms, after JVM has been warmed up (after >50 requests) it then takes 15-20ms. Still slower than RPCs 46ms that drops to 1 to 2ms. Client side RF takes 70ms to deserialise the response. Haven't got figures for RPC deserialisation but whole RPC request/response takes about 15ms. This was all in Firefox20. Chrome and IE10 were about 4x faster!Daina
Did you remove the gwt debug mode, this was slowing down gwt a lot a few years agoAwesome
Just firing a thought, I have seen your entity extends from EntityProxy but, have you tried with ValueProxy? The logic is simpler, there is no id to sync between server and client, and maybe your app does not need this feature.Aphonic
E
1

I'm not sure how relevant this is to your specific case, but the problem may be AutoBeans. RequestFactory makes extensive use of AutoBeans.

I have recently been able to solve a performance problem in a GWT application by reducing the use of AutoBeans, which seem to be very slow. The use of a hierarchical perfomance profiler such as the one in IE's F12 tools identified the Autobean code as the root of the problem, so the performance problem was client-side. IIRC the solution was to copy the AutoBeans to "real" Java objects after completion of the call.

Etamine answered 23/12, 2014 at 11:14 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.