Serialization Jackson vs Google Protocol Buffers

Where are many articles around comparing the serialization between different frameworks and of course different encodings. I came around recently the problem that I needed a very fast serialization for pretty simple objects but between different platforms (embedded device with C, Android Java, iOS Objective-C and Java Backend).

Well first reaction, let us just take JSON. So far so good. A bit unsatisfactory result is handling JSON in C. I remembered the good old Google Protocol Buffers. Googled around and was confused. Most post mentioned it is not faster then Jackson. I couldn’t believe this — as some years ago during some simple tests Protocol Buffers was around ten times faster. Well of course much time passed and so Jackson evolved a lot.

Time to compare again and see if it is worth even considering.

My requirements (yours may differ)

  1. Should be available in C / Java / iOS
  2. Should be really easy to use
  3. Should be really small on the wire — as we transfer a lot of small messages to mobile devices
  4. Should be as fast as possible (which basically means no XML please)
Note: Here I am not really focused on speed, but of course if something is 50% faster it is worth considering. Especially because of the mobile devices.

First simple run

Github Project

The first simple tests showed that it is around 10 times faster. Too much, so I checked for the lower and higher bounds and most (80%) of the messages was serialized in 0 ns.  Which forced me to increase the message complexity to ensure that 0ns wasn’t reached. Lets look into the results:

Macbook proto2 vs Jackson Performance

Even if a Macbook is maybe not the primary target we can already see that Protocol Buffers v2.6.x is nearly twice as fast during the serialization and and more the three times faster during the deserialization.

Serialization ns Deserialization ns
Jackson 1264 2037
Proto2 676 622
Wire 1329 1237

Compare different environments

To get the statistics just on a local development box isn’t too interesting. As if we look into binary protocols we are mostly looking on devices either in the IoT market or at least mobile devices. But it is also worth to double check you VM performance. We know they are just slow, as so the following results are somehow surprising.

Before you look into the stats, keep in mind that I had to take less cycles at the mobile device. The GC collection just killed the results a bit. Nevertheless the android device was faster before it start to gets quite slow.

Total Time Serialization & Deserialization

It quite obvious that we have a winner. Something we expected anyway if we are honest. Binary protocols should be faster. But if you look into all the numbers in detail it is quite interesting that the deserialization is in average much faster. Or in other words, where with Proto and Wire you have more or less the same performance deserialization with Jackson is slower compared to Jackson serialization.

Now it depends a bit on your use case. Are you devices usually receiving messages or sending messages.

What have we learned

Binary protocols are usually faster. So we are not betrayed by our gut feeling. Getting good numbers is pretty  hard, as so we shouldn’t just trust any numbers at the internet. For that reason I published the code on Github, please double check the numbers. A decision should be taken depending on the project, device and environment.

Even if Jackson is not the winner here, it is maybe still fast enough, for REST based services for sure the better choice. If we look into WebSockets, MQQT etc. we could consider using a binary protocol.

Paul Sterl has written 17 articles

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">