簡體   English   中英

在C#中解析JSON的最有效方法

[英]Most efficient way to parse JSON in C#

我想知道在C#中解析JSON的最有效方法是什么? 而且效率我指的是響應時間較短的那個。 我試圖使用幾種方法解析大量數據,這兩種方法的響應時間都很長。 誰能告訴我以下方法之間的區別? 是否有一種替代方案可以讓我以較低的響應時間進行解析?

選項1:

HttpWebRequest request = WebRequest.Create(jsonURL) as HttpWebRequest;
using (HttpWebResponse response = request.GetResponse() as HttpWebResponse)
{
    if (response.StatusCode != HttpStatusCode.OK)
        throw new Exception(String.Format(
        "Server error (HTTP {0}: {1}).",
        response.StatusCode,
        response.StatusDescription));
    DataContractJsonSerializer jsonSerializer = new DataContractJsonSerializer(typeof(obj));
    object objResponse = jsonSerializer.ReadObject(response.GetResponseStream());
}  

選項2:

var json = new WebClient().DownloadString(jsonURL);
using (MemoryStream ms = new MemoryStream(Encoding.Unicode.GetBytes(json)))
{
    DataContractJsonSerializer jsonSerializer = new DataContractJsonSerializer(typeof(obj));
    object objResponse = jsonSerializer.ReadObject(ms);
}  

您可以在以下鏈接中找到比較。

測試的庫:

http://sagistech.blogspot.com/2010/03/parsing-twitter-json-comparing-c.html

  • Json.NET - 一個流行的C#JSON庫。
  • Gapi.NET - Gapi.NET不是JSON解析庫,但它包含JSON解析例程。
  • Procurios - 又一個C#JSON庫。 另請參閱此博客文章,了解如何使用它來解析Twiter數據。
  • JavaScriptSerializer - .NET 3.5內置JSON解析器。
  • DataContractJsonSerializer - .NET 3.5內置JSON解析器。
  • AjaxPro - AC#AJAX庫。

在此輸入圖像描述


更新:

根據Matt Johnson的評論添加了此信息

http://theburningmonk.com/2011/11/performance-test-json-serializers-part-ii/

第一種方法有機會減少數據副本。 但我很難相信這兩種方法都會產生可衡量的差異。 您的實際成本將是網絡成本。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;


namespace Example
{
public static class JavascriptSerializator
{
    /// <summary>
    /// Serializes object to JSON from Microsoft
    /// </summary>
    /// <param name="objectForSerialization"></param>
    /// <returns></returns>
    public static string SerializeMJSON(this object objectForSerialization)
    {
        try
        {
            System.Web.Script.Serialization.JavaScriptSerializer s = new System.Web.Script.Serialization.JavaScriptSerializer();

            return s.Serialize(objectForSerialization);
        }
        catch (Exception ex)
        {
            /// Handle exception and throw it ...
        }

    }

    /// <summary>
    /// Deserializes object from Microsoft JSON string
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="str"></param>
    /// <returns></returns>
    public static T DeserializeMJSON<T>(this string str)
    {
        try
        {
            System.Web.Script.Serialization.JavaScriptSerializer s = new System.Web.Script.Serialization.JavaScriptSerializer();

            return s.Deserialize<T>(str);
        }
        catch (Exception ex)
        {
            //// Handle the exception here...
        }

    }
}

}

仍處於早期階段,但我在Json.NET之上構建了一個代碼生成器,它消除了反射並加速了反序列化4倍。

結帳CGbR JSON目標

[DataContract]
public partial class Root
{
    [DataMember]
    public int Number { get; set; }

    [DataMember]
    public Partial[] Partials { get; set; }

    [DataMember]
    public IList<ulong> Numbers { get; set; }
}

將生成一個部分類:

public Root FromJson(JsonReader reader)
{
    while (reader.Read())
    {
        // Break on EndObject
        if (reader.TokenType == JsonToken.EndObject)
            break;

        // Only look for properties
        if (reader.TokenType != JsonToken.PropertyName)
            continue;

        switch ((string) reader.Value)
        {
            case "Number":
                reader.Read();
                Number = Convert.ToInt32(reader.Value);
                break;

            case "Partials":
                reader.Read(); // Read token where array should begin
                if (reader.TokenType == JsonToken.Null)
                    break;
                var partials = new List<Partial>();
                while (reader.Read() && reader.TokenType == JsonToken.StartObject)
                    partials.Add(new Partial().FromJson(reader));
                Partials = partials.ToArray();
                break;

            case "Numbers":
                reader.Read(); // Read token where array should begin
                if (reader.TokenType == JsonToken.Null)
                    break;
                var numbers = new List<ulong>();
                while (reader.Read() && reader.TokenType != JsonToken.EndArray)
                    numbers.Add(Convert.ToUInt64(reader.Value));
                Numbers = numbers;
                break;

        }
    }

    return this;
}

出於好奇,我有JSON.NET 5.0 r8和我自己的(只有~500行代碼)玩具JSON解析器吃各種JSON文件大小有或沒有循環,從幾十個角色球場到一個180 MB JSON文件,例如“真實”數據。

可以在此處找到樣本數據(包括12mb JSON,但不包括可在其他地方找到的180mb)以及附帶的詳細信息,例如從流解析到反序列化為POCO(強類型)對象的示例:

https://github.com/ysharplanguage/FastJsonParser

'希望能幫助到你。

PS很好的鏈接,知道,順便說一下,Chamika已經在他的評論中提供了。

編輯

在我忘記之前(或者只是在它被忽略的情況下),這是必須知道/必須閱讀的那種,IMO,盡可能強調CLR的大對象堆的重要性,這要歸功於流式讀取JSON您的代碼消耗,特別是在Web服務器環境的上下文中:

http://insidethecpu.wordpress.com/2013/06/19/json-parsing/

PPS(因此是Program.cs中的最后一次測試,用於測試/展示我鏈接到的玩具解析器,上面)

“HTH!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM