Fork on Github
Download the Nuget package
The last tutorial focused on parsing embedded JSON objects. This time, we’ll focus on serialising simple objects in C#.
Object serialisation using JSON# is 25 times to several hundred times faster than serialisation using JSON.NET, on a quad-core CPU with 16GB RAM. The source code is written in a BDD-manner, and the associated BDD features contain performance tests that back up these figures.
Let’s start with a basic class in C#:
class SimpleObject { public string Name { get; set; } public int Count { get; set; } }
Our first step is to provide serialisation metadata to JSON#. Traditionally, most frameworks use Reflection to achieve this. While this works very well, it requires the component to know specific assembly metadata that describes your object. This comes with a slight performance penalty.
Ideally, when leveraging Reflection, the optimal design is a solution that reads an object’s assembly metadata once, and caches the result for the duration of the application’s run-time. This is generally not achievable with stateless HTTP calls. Using Reflection, we will likely query the object’s assembly during each HTTP request when serialising or de-serialising an object, suffering the associated performance-overhead for each request.
JSON# allows us to avoid that overhead by exposing serialisation metadata in the class itself:
class SimpleObject : IHaveSerialisableProperties { public string Name { get; set; } public int Count { get; set; } public virtual SerialisableProperties GetSerializableProperties() { return new SerialisableProperties("simpleObject", new List<JsonProperty> { new StringJsonProperty { Key = "name", Value = Name }, new NumericJsonProperty { Key = "count", Value = Count } }); } }
First, we need to implement the IHaveSerialisableProperties
interface, allowing JSON# to serialise our object. Notice the new method, GetSerializableProperties
, that returns a SerialisableProperties
object, which looks like this:
public class SerialisableProperties { public string ObjectName { get; set; } public IEnumerable<JsonProperty> Properties { get; private set; } public IEnumerable<JsonSerialisor> Serialisors { get; set; } public SerialisableProperties(IEnumerable<JsonProperty> properties) { Properties = properties; } public SerialisableProperties(IEnumerable<JsonSerialisor> serialisors) { Serialisors = serialisors; } public SerialisableProperties(string objectName, IEnumerable<JsonProperty> properties) : this(properties) { ObjectName = objectName; } public SerialisableProperties(string objectName, IEnumerable<JsonSerialisor> serialisors) : this(serialisors) { ObjectName = objectName; } public SerialisableProperties(IEnumerable<JsonProperty> properties, IEnumerable<JsonSerialisor> serialisors) : this(properties) { Serialisors = serialisors; } public SerialisableProperties(string objectName, IEnumerable<JsonProperty> properties, IEnumerable<JsonSerialisor> serialisors) : this(properties, serialisors) { ObjectName = objectName; } } }
This object is essentially a mapper that outlines how an object should be serialised. Simple types are stored in the Properties property, while more complex types are retrieved through custom JsonSerialisor
objects, which I will discuss in the next tutorial. The following code outlines the process involved in serialising a SimpleObject
instance:
First, we initialise our object
var simpleObject = new SimpleObject {Name = "Simple Object", Count = 10};
Now initialise a BinaryWriter
, setting the appropriate Encoding. This will be used to build the object’s JSON-representation, under-the-hood.
var writer = new BinaryWriter(new MemoryStream(), new UTF8Encoding(false));
Now we use our Json
library to serialise the object
var serialisableProperties = simpleObject.GetSerializableProperties(); byte[] serialisedObject; using (var serialisor = new StandardJsonSerialisationStrategy(writer)) { Json.Serialise(serialisor, new JsonPropertiesSerialisor(serialisableProperties)); serialisedObject = serialisor.SerialisedObject; }
Below is the complete code-listing:
var simpleObject = new SimpleObject {Name = "Simple Object", Count = 10}; var writer = new BinaryWriter(new MemoryStream(), new UTF8Encoding(false)); var serialisableProperties = simpleObject.GetSerializableProperties(); byte[] serialisedObject; using (var serialisor = new StandardJsonSerialisationStrategy(writer)) { Json.Serialise(serialisor, new JsonPropertiesSerialisor(serialisableProperties)); serialisedObject = serialisor.SerialisedObject; }
Now our serialisedObject
variable contains a JSON-serialised representation of our SimpleObject
instance, as an array of raw bytes. We’ve achieved this without Reflection, by implementing a simple interface, IHaveSerialisableProperties
in our SimpleObject
class, and have avoided potentially significant performance-overhead; while a single scenario involving reflection might involve very little performance-overhead, consider a web application under heavy load, leveraging Reflection. We can undoubtedly support more concurrent users per application tier if we avoid Reflection. JSON# allows us to do just that.
In the next tutorial, I’ll discuss serialising complex objects.
Connect with me: