gson vs. jackson

1,365 views
Skip to first unread message

Joel

unread,
Oct 19, 2009, 12:56:25 AM10/19/09
to google-gson
Hi guys,

We like Gson, but we're spending a lot of time there. I read this
with interest:

http://www.cowtowncoder.com/blog/archives/2009/09/entry_326.html

and I'm curious if anyone has any opinions about Jackson, or about
making Gson more performant.

Thanks!

Joel

inde...@gmail.com

unread,
Oct 19, 2009, 2:53:04 AM10/19/09
to google-gson
My instinctive reaction would be to somewhat skeptical of the results
since they show an order of magnitude difference. For simple object
writing or parsing, Gson does nothing special and should be reasonably
fast. I would be curious to know the exact code that is being used to
run the benchmark. I tried finding it at the page but couldn't. There
is a small snippet, but it is not clear what object is being written/
read. Moreover, it is not clear if Gson is being recreated every time
(which will cause a lot of overhead. Gson is thread-safe, so the same
instance should be used over and over again. There is a fairly large
cost of creating the Gson object).

Finally, Gson 1.4 contains a few changes that increases the array
parsing capacity manifolds.

Inder

Joel

unread,
Oct 19, 2009, 10:25:41 AM10/19/09
to google-gson
You're right, 1.4 is better. It's not only capable of larger
payloads, it's maybe 25% faster, even for smaller ones.

I'll write my own benchmark and let you know what I learn.

Ian Clarke

unread,
Oct 19, 2009, 4:38:43 PM10/19/09
to googl...@googlegroups.com
I'd be interested in this as with the application I'm using Gson in
currently, parsing and generating JSON is a significant proportion of
my CPU load.

In the current version, which still uses Json Lib, generating a JSON
response is the biggest single contributor to the time required to
respond to an API request. The upcoming version uses Gson.

Ian.
--
Ian Clarke
CEO, Uprizer Labs
Email: i...@uprizer.com
Ph: +1 512 422 3588

Joel

unread,
Oct 19, 2009, 6:49:20 PM10/19/09
to google-gson
Some interesting results for serializing a long array:

2009-10-19 15:38:44,389 [main] INFO foo - COMPARE SERIALIZATION
2009-10-19 15:38:51,062 [main] INFO foo - gson serialization (ns):
66421766
2009-10-19 15:38:51,324 [main] INFO foo - jackson serialization
(ns): 1213741

so, 66ms for gson, 1.2ms for jackson. see the code below.

Interestingly, removing the @Expose annotations (which are not used
for this case anyway), yields a big change:

2009-10-19 15:42:25,299 [main] INFO foo - COMPARE SERIALIZATION
2009-10-19 15:42:28,177 [main] INFO foo - gson serialization (ns):
28148362
2009-10-19 15:42:28,444 [main] INFO foo - jackson serialization
(ns): 1664830

This is on a core 2 duo 2.8GHz ubuntu 9.04 (2.6.28), hotspot 14.2 jvm
1.6.0_16.

I'd be curious if anyone else can duplicate these results.

public class PerformanceTest {
public static class SampleClass {
@Expose
public String foo;
@Expose
public List<AnotherSampleClass> bar = new
ArrayList<AnotherSampleClass>();
}
public static class AnotherSampleClass {
@Expose
public String foo;
public AnotherSampleClass(String foo) {
this.foo = foo;
}
}
@Test
public void gsonVsJackson() throws JsonGenerationException,
JsonMappingException, IOException {
Logger.getLogger("foo").info("COMPARE SERIALIZATION");
SampleClass c = new SampleClass();
c.foo = "hi";
c.bar.add(new AnotherSampleClass("hi"));
for (int i = 0; i < 5000; ++i) {
c.bar.add(new AnotherSampleClass("hi"));
}
int iterations = 100;
{
Gson g = new GsonBuilder().create();
StringWriter w = new StringWriter();
long t1 = System.nanoTime();
for (int i = 0; i < iterations; ++i) {
g.toJson(c, w);
}
long t2 = System.nanoTime();
Logger.getLogger("foo").info("gson serialization (ns): " +
String.valueOf( (t2 - t1) / iterations));
}
{
ObjectMapper m = new ObjectMapper();
StringWriter w = new StringWriter();
long t1 = System.nanoTime();
for (int i = 0; i < iterations; ++i) {
m.writeValue(w, c);
}
long t2 = System.nanoTime();
Logger.getLogger("foo").info("jackson serialization (ns):
" + String.valueOf( (t2 - t1) / iterations));

inde...@gmail.com

unread,
Oct 19, 2009, 8:08:25 PM10/19/09
to google-gson
I added some tests to measure the serialization and deserialization
performance of Gson (based on your code):

See http://code.google.com/p/google-gson/source/detail?r=508

Here are the numbers that I got:
Serialize classes avg time: 60 ms
Deserialized classes avg time: 70 ms
Serialize exposed classes avg time: 159 ms
Deserialized exposed classes avg time: 173 ms

On a somewhat loaded dual two-core opteron machine .

You are right the Expose annotation is adding quite a bit of overhead.
We will investigate and see if we can reduce it.

Thanks
Inder

Joel

unread,
Oct 20, 2009, 9:59:07 PM10/20/09
to google-gson
I think you've probably already discovered this, but the speed impact
of field annotations doesn't actually depend on the annotation itself
(i.e. @Foo has the same effect as @Expose), but the speed impact *is*
dependent, linearly, on the number of annotations on a field.

2009-10-20 14:37:25,992 [main] INFO foo - NO ANNOTATIONS
2009-10-20 14:37:48,529 [main] INFO foo - gson serialization (ns):
22504527
2009-10-20 14:37:48,529 [main] INFO foo - EXPOSE ANNOTATION
2009-10-20 14:39:03,070 [main] INFO foo - gson serialization (ns):
74538016
2009-10-20 14:39:03,070 [main] INFO foo - OTHER ANNOTATION
2009-10-20 14:40:12,367 [main] INFO foo - gson serialization (ns):
69295546
2009-10-20 14:40:12,367 [main] INFO foo - SIX ANNOTATION
2009-10-20 14:44:23,949 [main] INFO foo - gson serialization (ns):
251581459

This problem seems to be caused by the
SerializedNameAnnotationInterceptNamingPolicy, which probes for the
SerializedName annotation, and which can't be removed.

A quick fix removes the wrapping:

--- lib/prod/gson/gson-1.4/com/google/gson/GsonBuilder.java (revision
2350)
+++ lib/prod/gson/gson-1.4/com/google/gson/GsonBuilder.java (working
copy)
@@ -222,8 +222,7 @@
* @since 1.3
*/
public GsonBuilder setFieldNamingStrategy(FieldNamingStrategy
fieldNamingStrategy) {
- this.fieldNamingPolicy =
- new SerializedNameAnnotationInterceptingNamingPolicy
(fieldNamingStrategy);
+ this.fieldNamingPolicy = fieldNamingStrategy;
return this;
}

and gets the speed back up to the "no annotation" case.

2009-10-20 17:05:24,817 [main] INFO foo - SIX ANNOTATION WITH MY
NAMING STRATEGY
2009-10-20 17:05:45,763 [main] INFO foo - gson serialization (ns):
20836147

it's pretty amazing to me that Field.getAnnotation() is so incredibly
slow, but there you go.

Anyway, I added a couple of caches for some of the reflection lookups,
and it helped a little, e.g. ObjectNavigator,
AnonymousAndLocalClassExclusionStrategy.

Still 10X slower than Jackson, though.


Joel



On Oct 19, 5:08 pm, "inder...@gmail.com" <inder...@gmail.com> wrote:
> I added some tests to measure the serialization and deserialization
> performance of Gson  (based on your code):
>
> Seehttp://code.google.com/p/google-gson/source/detail?r=508
Reply all
Reply to author
Forward
0 new messages