Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Json.net slow serialization and deserialization

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?

like image 702
Thaven Avatar asked Apr 10 '12 13:04

Thaven


People also ask

Is JSON deserialization slow?

There is a common step when writing an API that returns a JSON formatted file, which is the deserialization of the data content which can cause slowness.

Is JSON net deprecated?

Json was basically scrapped by Microsoft with the coming of . NET Core 3.0 in favor of its newer offering designed for better performance, System. Text.

Is System text JSON faster than Newtonsoft?

As can be seen above, the System. Text. Json is much faster than the Newtonsoft. Json.

Is Newtonsoft JSON obsolete?

The Newtonsoft. Json. Schema namespace provides classes that are used to implement JSON schema. Obsolete.


2 Answers

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.

like image 128
Frog Pr1nce Avatar answered Sep 18 '22 17:09

Frog Pr1nce


What I believe is happening here is that you are getting a delay when the Json.Net library is being loaded. You should try compiling in Release mode to see if things speed up considerably, as this should prevent symbols from being loaded (which can add to the library load time).

If it is still an issue, find a good time in your app that you can do a dummy serialization (perhaps even on a background thread) to force the library to load. That has a bit of code-smell to it, though, so there may be a better way of forcing the load, but that's a brute force method that should work all the time.

like image 25
Robaticus Avatar answered Sep 21 '22 17:09

Robaticus