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)
- Should be available in C / Java / iOS
- Should be really easy to use
- Should be really small on the wire — as we transfer a lot of small messages to mobile devices
- Should be as fast as possible (which basically means no XML please)
First simple run
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:
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.
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.