Json.net slow serialization and deserialization

Thaven picture Thaven · Apr 10, 2012 · Viewed 16k times · Source

I have a problem - Json.Net serializing my objects realy slow. I have some basic class:

public class authenticationRequest
{
    public string userid;
    public string tid;
    public string token;
    public string platform;
    public string version;
}

And I'm serializing it with

string jsonDataToSend = JsonConvert.SerializeObject(dataToSend); 

This operation takes about 1900 ms. In compare to info from Json.net CodePlex page:

enter image description here

It takes a really long time. For test purposes I swapped my class for a simple string:

string jsonDataToSend = JsonConvert.SerializeObject("fsdfsdfsdfs");

And it still takes ~900 ms to convert. What is the reason? What I can do to serialize this data faster?

Answer

Frog Pr1nce picture Frog Pr1nce · Feb 5, 2015

I had the same problem with a project I'm working on and I solved it by following the advice on this page: http://www.newtonsoft.com/json/help/html/Performance.htm

Specifically, they recommend manually serializing your objects when performance is critical:

public static string ToJson(this Person p)
{
    StringWriter sw = new StringWriter();
    JsonTextWriter writer = new JsonTextWriter(sw);

    // {
    writer.WriteStartObject();

    // "name" : "Jerry"
    writer.WritePropertyName("name");
    writer.WriteValue(p.Name);

    // "likes": ["Comedy", "Superman"]
    writer.WritePropertyName("likes");
    writer.WriteStartArray();
    foreach (string like in p.Likes)
    {
        writer.WriteValue(like);
    }
    writer.WriteEndArray();

    // }
    writer.WriteEndObject();

    return sw.ToString();
}

My example in VB looks like this:

    Public Function SerializeWords(ByRef oWords As List(Of Word))
        Dim sb As New StringBuilder
        Dim sw As New IO.StringWriter(sb)
        Using oWriter As Newtonsoft.Json.JsonWriter = New Newtonsoft.Json.JsonTextWriter(sw)
            With oWriter
                .WriteStartArray()
                For Each oWord As Word In oWords
                    .WriteStartObject()

                    .WritePropertyName("ID")
                    .WriteValue(oWord.ID)

                    .WritePropertyName("Phonics")
                    .WriteValue(oWord.Phonics)

                    .WritePropertyName("Word_")
                    .WriteValue(oWord.Word_)

                    .WritePropertyName("WordLength")
                    .WriteValue(oWord.WordLength)

                    .WriteEndObject()
                Next
                .WriteEndArray()

            End With
        End Using
        Return sb.ToString

    End Function

Notice how it's strongly typed. I believe when you use Newtonsoft.Json.JsonConvert.SerializeObject() it's using reflection to get the job done (which can really add up when you have many objects with many properties).

Anyways... once I wrote my own serializer, my time serializing a list of 250 words went from 28 seconds using JsonConvert.SerializeObject() method to 31 milliseconds using my own function.