nmorel / gwt-jackson

gwt-jackson is a JSON parser for GWT. It uses Jackson 2.x annotations to customize the serialization/deserialization process.
Apache License 2.0
111 stars 55 forks source link

slow decoding performance #99

Open nlight-jdev opened 8 years ago

nlight-jdev commented 8 years ago

I'm running a benchmark with RestyGWT hoping to get a better performance than GWT-RPC. Currently with GWT-RPC the response payload(~600KB) is parsed in 75ms. With RestyGWT + JSONParser in 200ms. With RestyGWT + GwtJackson in 600ms.

Are there any ways to improve on this? Why is GwtJackson 3 times slower than JSONParser and GWT-RPC?

nmorel commented 8 years ago

I did some benchmark a while ago and it always beat GWT-RPC. That's the main reason I kept working on this project because we switch to it for performance on a big project.
But maybe I introduced some regression into it after those tests!

Can you give more details on your procedure ? Did you activate the disableCastChecking and disableClassMetadata option on gwt compiler ?

I wrote a little benchmark project here. It was comparing RestyGWT with gwt-jackson. But I wasn't sure the test was good so I never published the result.

ibaca commented 8 years ago

If you are concerned about performance you can always use Ovelays/JsInterop, zero overhead 😵.

nlight-jdev commented 8 years ago

@nmorel thanks for the detailed answer. I've tested with your suggestion, there is a small improvement but still behind GWT-RPC.

The above timings were in SuperDevMode, in production build I get with RestyGWT+GWTJackson:

The procedure, on server-side I use CXF or Jersey(both similar performance) to get a 600KB JSON response. To measure performance I've a Stopwatch started before the request and measured in the AsyncCallback#onSuccess.

You said something about a regression, is there a more performant GWTJackson version before you did the changes?

Thanks a lot!

nlight-jdev commented 8 years ago

@ibaca - thanks as well for suggestion. can Overlays/JsInterop be integrated with GWTJackson or RestyGWT with little or no overhead?

nmorel commented 8 years ago

@nlight-dev no specific version. But since I did my benchmark between RequestFactory/GWT-RPC/REST, I added a lot of functionality and annotation's support. I wouldn't be surprised that some of this code slow down the deserialization process.

Do you use any specific Jackson annotations or just plain object ?

You are testing the whole request so it includes the serialization of the response on server-side (and the deserialization of the request body if you have one). It might be slower than RPC.

When optimizing our performance, I also added the jackson module Afterburner on server side. It won't improve the time of the first request but you should notice a difference on the next ones.

I think GWT-RPC gzip its response reducing the transport time between server and client. Do you compress your JSON response ?

The best would be to only compare the deserialization phase of GWT-RPC and GWT Jackson. But I don't know how to do that in RPC.

And for overlay, gwt-jackson has basic support for object extending JavascriptObject. If you use one in one of your field or as root object, it'll detect it and use JsonUtils.safeEval() to decode the object and stringify to encode it.

nlight-jdev commented 8 years ago

I've used plain objects, some of them were interfaces with @JsonSubTypes annotation to expose the implementing types. The JSON response was compressed on server-side both for CXF and Jersey.

To have an idea of the server-side performance, I'm looking at Chrome DevTools/Time column. The values are very similar between the server-side RPC vs Jersey/CXF. Also, did some profiling in the Profiles tab and most of the time is spent in deserializing the response JSON.

ibaca commented 8 years ago

RestyGWT is a transport library, which originally includes a coding/decoding lib, but I think that now RestyGWT recommend that you use this coding/decoding lib. In the transport layer, you should use RestyGWT or other like GWT RequestBuilder or the cool AutoREST 😛, AutoREST was born as a RestyGWT without encode/decode code.

So, what I means with JsInterop/Overlay is that instead of using a decoding-mapping library like GWT Jackson, you can just use the browser native JSON.parse and access the native JSON object using GWT, which nowadays can be done using JsInterop/Overlays. As you remove all the mapping and use the native json parser I consider that a "zero overhead".

You are asking if this can be used with RestyGWT (or other transport lib), and yes you can use the RestGWT Overlay support (example here) or you can also just return obtain the response String and use JsonUtils.safeEval as @nmorel said.