Json.NET Performance With Binary Data
Binary data and text file formats (JSON, XML) don’t tend get along. To be included in JSON or XML binary data has to be encode into a text friendly format, generally base64, which creates overhead both in the time spent encoding/decoding binary, and the extra size of the text encoded data in the message.
{
"binary": "SGVsbG8gV29ybGQ="
}
The Test
In our test we’ll compare serializing a message with binary data using common .NET serialization methods and compare the result. First our message…
public class Image
{
public string FileName { get; set; }
public string Author { get; set; }
public string Caption { get; set; }
public byte[] Data { get; set; }
}
And some test data…
FileName: bunny_pancake.jpg Author: Hironori Akutagawa Caption: I have no idea what you are talking about so here’s a bunny with a pancake on its head.
The Results
Json.NET and the DataContractSerializer are about equal to each other in the size of the resulting message – each is encoding the image byte array as base64 encoded text. The small edge to Json.NET comes from the smaller size of the JSON metadata compared to the DataContractSerializer’s XML.
Json.NET BSON and the BinaryFormatter are binary formats so they can include the image data directly in the message. They’re approximately 25% smaller than JSON/XML by saving the overhead of base64. Again the Json.NET BSON format is more efficient than the BinaryFormatter making it slightly smaller.
Finally as you can see the WCF DataContractJsonSerializer is by far the least efficient. When I looked into why it performed so badly it turns out that the WCF JsonSerializer serializes binary data as a JSON array of integers, one integer representing each byte. It goes without saying that you should never use the WCF JsonSerializer with binary data.