简体   繁体   English

Json.net 序列化和反序列化缓慢

[英]Json.net slow serialization and deserialization

I have a problem - Json.Net serializing my objects realy slow.我有一个问题 - Json.Net 序列化我的对象真的很慢。 I have some basic class:我有一些基本的 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.此操作大约需要 1900 毫秒。 In compare to info from Json.net CodePlex page:与来自Json.net CodePlex页面的信息相比:

在此处输入图像描述

It takes a really long time.这需要很长时间。 For test purposes I swapped my class for a simple string:出于测试目的,我将 class 换成了一个简单的字符串:

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

And it still takes ~900 ms to convert.转换仍然需要 ~900 毫秒。 What is the reason?是什么原因? What I can do to serialize this data faster?我可以做些什么来更快地序列化这些数据?

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我正在处理的项目遇到了同样的问题,我按照此页面上的建议解决了这个问题: 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:我在 VB 中的示例如下所示:

    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).我相信当您使用Newtonsoft.Json.JsonConvert.SerializeObject()时,它正在使用反射来完成工作(当您有许多具有许多属性的对象时,这真的会加起来)。

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.无论如何...一旦我编写了自己的序列化程序,我序列化 250 个单词列表的时间从使用 JsonConvert.SerializeObject() 方法的 28 秒变为使用我自己的 function 的 31 毫秒。

What I believe is happening here is that you are getting a delay when the Json.Net library is being loaded.我相信这里发生的是,当加载 Json.Net 库时,您会遇到延迟。 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).您应该尝试在 Release 模式下编译以查看速度是否大大加快,因为这应该可以防止加载符号(这会增加库加载时间)。

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.不过,这有点代码味道,因此可能有更好的强制加载方法,但这是一种应该一直有效的蛮力方法。

JSON string deserialization using the "Newtonsoft.Json" library works much faster for me on ARM when deserializing to the dynamic data type instead of a custom one. JSON 使用“Newtonsoft.Json”库的字符串反序列化在 ARM 上对我来说更快,当反序列化为dynamic数据类型而不是自定义数据类型时。

var receivedObject = JsonConvert.DeserializeObject<dynamic>(content);

but this is even faster:但这更快:

dynamic receivedObject = JObject.Parse(content);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM