Json.net 序列化和反序列化速度慢

13

我有一个问题——Json.Net序列化我的对象非常缓慢。我有一些基本类:

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

并且我正在使用序列化进行编码。

string jsonDataToSend = JsonConvert.SerializeObject(dataToSend); 

这个操作大约需要1900毫秒时间。与Json.net CodePlex页面提供的信息相比:

enter image description here

那需要很长时间。为了测试目的,我将我的类替换为一个简单的字符串:

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

转换仍然需要大约900毫秒。原因是什么?我该如何更快地序列化这些数据?


1
你是否连接了调试器?这个问题是否一直出现? - Daniel A. White
1
你运行了多次迭代吗? - Daniel A. White
1
如果您运行序列化两次,第二次需要花费同样的时间吗? - Robaticus
2
尝试连续运行两次,看看第二次的时间是多少。可能是构造函数或加载库需要额外的时间。(不用担心构造函数。我刚刚查看了源代码,发现没有构造函数)。 - Robaticus
就我所知,我已经研究了同样的问题几天了。我有一个大的JSON字符串,反序列化大约需要70秒。但是当我不在调试模式下运行它时...只需要0.5秒。 - Peter
显示剩余7条评论
3个回答

18

我在处理一个项目时遇到了同样的问题,我通过遵循这个页面上的建议解决了它: http://www.newtonsoft.com/json/help/html/Performance.htm

具体来说,当性能关键时,他们建议手动序列化你的对象:

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();
}

我的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

注意它是强类型的。我相信当您使用Newtonsoft.Json.JsonConvert.SerializeObject()时,它会使用反射来完成任务(如果您有许多具有许多属性的对象,则这可能会增加时间)。

无论如何......一旦我编写了自己的序列化器,我的时间将一个包含250个单词列表进行序列化,从使用JsonConvert.SerializeObject()方法的28秒缩短到使用我的自定义函数的31毫秒。


5
我认为这里发生的情况是Json.Net库加载时出现了延迟。你应该尝试在发布模式下编译,看看是否可以显著提高速度,因为这样可以防止符号被加载(这会增加库加载时间)。
如果仍然存在问题,在应用程序中找到一个适当的时间进行虚拟序列化(甚至可以在后台线程上执行),以强制加载库。但这个方法有一点代码异味,可能有更好的方法来强制加载,但这是一个能够始终奏效的蛮力方法。

1

使用“Newtonsoft.Json”库进行JSON字符串反序列化时,如果反序列化为dynamic数据类型而不是自定义类型,则在ARM上的速度要快得多。

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

但这更快:
dynamic receivedObject = JObject.Parse(content);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接