danielwertheim

danielwertheim


notes from a passionate developer

Share


Sections


Tags


Disclaimer

This is a personal blog. The opinions expressed here represent my own and not those of my employer, nor current or previous. All content is published "as is", without warranty of any kind and I don't take any responsibility and can't be liable for any claims, damages or other liabilities that might be caused by the content.

Json.Net vs ServiceStack.Text

This is going to be a verry short comparision of the two Json-serialization frameworks:

I have always used Json.Net when dealing with serialization of entities back and forth to Json, but then I stumbled upon this:

Fastest JSON Serializer for .NET released - http://www.servicestack.net/mythz_blog/?p=344

Man was I excited, since I need the "best" performance I can get for this in SisoDb.

Lets do a simple test

I just downloaded the latest version of both libraries (Json.Net - changeset: 57577), (ServiceStack.Text - changeset: c3e5d0c, v1.8), compiled them for .Net 4.0 Client profile and put together a very simple example. Note, I'm not testing features here, just raw serialization and deserialization. I don't know if you can "tweak" ServiceStack.Text as much as you can with Json.Net, e.g: Strategies for null property handling, missing member, indentation of Json etc.

The Item being serialized

[Serializable]
public class Customer
{
    public int Id { get; set; }
    public int CustomerNo { get; set; }
    public string Firstname { get; set; }
    public string Lastname { get; set; }
    public ShoppingIndexes ShoppingIndex { get; set; }
    public DateTime CustomerSince { get; set; }
    public Address BillingAddress { get; set; }
    public Address DeliveryAddress { get; set; }

    public Customer()
    {
        ShoppingIndex = ShoppingIndexes.Level0;
        BillingAddress = new Address();
        DeliveryAddress = new Address();
    }
}

[Serializable]
public class Address
{
    public string Street { get; set; }
    public string Zip { get; set; }
    public string City { get; set; }
    public string Country { get; set; }
    public int AreaCode { get; set; }
}

[Serializable]
public enum ShoppingIndexes
{
    Level0 = 0,
    Level1 = 10,
    Level2 = 20,
    Level3 = 30
}

The Test application

static void Main(string[] args)
{
    var numberOfCustomers = 100000;
    var numberOfItterations = 5;

    //Console.WriteLine("Json.Net");
    //TimeSerializationAction(
    //  SerializeUsingJsonNet, numberOfCustomers, numberOfItterations);
    //TimeDeserializationAction(
    //  Newtonsoft.Json.JsonConvert.SerializeObject, DeSerializeUsingJsonNet,
    //  numberOfCustomers, numberOfItterations);

    //Console.WriteLine("ServiceStack.Text");
    //TimeSerializationAction(
    //  SerializeUsingServiceStackText, numberOfCustomers, numberOfItterations);
    //TimeDeserializationAction(
    //  ServiceStack.Text.JsonSerializer.SerializeToString, DeserializeUsingServiceStackText, 
    //  numberOfCustomers, numberOfItterations);

    Console.ReadKey();
}

private static void SerializeUsingJsonNet(IEnumerable<Customer> customers)
{
    var json = customers.Select(Newtonsoft.Json.JsonConvert.SerializeObject).ToList();
}

private static void DeSerializeUsingJsonNet(IEnumerable<string> json)
{
    var customers = json.Select(
        Newtonsoft.Json.JsonConvert.DeserializeObject<Customer>).ToList();
}

private static void SerializeUsingServiceStackText(IEnumerable<Customer> customers)
{
    var json = customers.Select(ServiceStack.Text.JsonSerializer.SerializeToString).ToList();
}

private static void DeserializeUsingServiceStackText(IEnumerable<string> json)
{
    var customers = json.Select(
        ServiceStack.Text.JsonSerializer.DeserializeFromString<Customer>).ToList();
}

private static void TimeSerializationAction(
    Action<IList<Customer>> action,
    int numOfCustomers,
    int numOfItterations)
{
    var stopWatch = new Stopwatch();

    for (var c = 0; c < numOfItterations; c++)
    {
        var customers = CustomerFactory
            .CreateCustomers(numOfCustomers);

        stopWatch.Start();
        action(customers);
        stopWatch.Stop();

        Console.WriteLine(
            "TotalSeconds = {0}",
            stopWatch.Elapsed.TotalSeconds);

        stopWatch.Reset();
    }
}

private static void TimeDeserializationAction(
    Func<Customer, string> serializer,
    Action<IList<string>> action,
    int numOfCustomers,
    int numOfItterations)
{
    var stopWatch = new Stopwatch();

    for (var c = 0; c < numOfItterations; c++)
    {
        var customerJsons = CustomerFactory
            .CreateCustomers(numOfCustomers)
            .Select(serializer)
            .ToList();

        stopWatch.Start();
        action(customerJsons);
        stopWatch.Stop();

        Console.WriteLine(
            "TotalSeconds = {0}",
            stopWatch.Elapsed.TotalSeconds);

        stopWatch.Reset();
    }
}

Results

Each step: Serialization and Deserialization; has been executed one scenario at a time for each framework. Doing serialization in one execution and deserialization in another. Each time five iterations with 100000 customers in each iteration.

Scenarios: Serialization and Deserialization for:

Measurements

Average values

Now you can decide for your self. I will continue with ServiceStack.Text, especially since deserialization is of greater importance for my project SisoDb.

Download the example code and Excel with the results.

//Daniel

View Comments