10

I was wondering what is the most efficient way to parse JSON in C#? And by efficient I mean the one with the lower response time. I am trying to parse a large amount of data using a couple of methods, and response time in both of these methods are high. Can anyone tell me the difference between the following methods? Is there an alternative that would let me parse with a lower response time?

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

Option 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);
}  
Brian
  • 5,069
  • 7
  • 37
  • 47
Gonzalo
  • 982
  • 6
  • 23
  • 39
  • Well... how large is your data exactly ? Define what you mean by "High" response time for now ? have you already identified if the bottleneck was the network or the treatment ? – Laurent S. Apr 18 '13 at 16:23
  • Try with ServiceStack,Json.Net,JavaScriptSerializer etc. and see the result. – I4V Apr 18 '13 at 16:28
  • 1
    http://www.servicestack.net/benchmarks/ – I4V Apr 18 '13 at 16:39

5 Answers5

13

You can find a comparison in following link.

The libraries tested:

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

  • Json.NET - A popular C# JSON library.
  • Gapi.NET - Gapi.NET is not a JSON parsing library, but it contains JSON parsing routines.
  • Procurios - Yet another C# JSON library. See also this blog post how to use it to parse Twiter data.
  • JavaScriptSerializer - .NET 3.5 built-in JSON parser.
  • DataContractJsonSerializer - .NET 3.5 built-in JSON parser.
  • AjaxPro - A C# AJAX library.

enter image description here


Updated:

Added this information based on Matt Johnson's comment

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

Chamika Sandamal
  • 23,565
  • 5
  • 63
  • 86
  • 1
    Don't forget [ServiceStack.Text](https://github.com/ServiceStack/ServiceStack.Text). Benchmarks [here](http://theburningmonk.com/2011/11/performance-test-json-serializers-part-ii/). – Matt Johnson-Pint Apr 18 '13 at 16:40
  • Thanks for the answers! According to Sagi's blog, Json is better than DataContractJsonSerializer, but according to Matt's link, DataContract is better.. Have you had a change to compare Gapi.NET vs ServiceStack.Text? – Gonzalo Apr 18 '13 at 17:02
  • 1
    @Gonzalo - Personally, I use JSON.Net. All of these benchmarks are outdated, I haven't seen a recent one - so I have no idea who is presently the fastest. However you look at it, these are milliseconds difference at most. JSON.Net is the most widely implemented, very stable, and very flexible. I value that more than I value raw performance. – Matt Johnson-Pint Apr 18 '13 at 17:06
  • 1
    And even Microsoft has stopped using `DataContractJsonSerializer` and `JavascriptSerializer`. All the new stuff (like MVC4) comes with JSON.Net. – Matt Johnson-Pint Apr 18 '13 at 17:08
  • +1 for flexibility of JSON.NET, and I think recent releases have been focusing on improved performance. – Brandon Apr 18 '13 at 19:02
  • @MattJohnson After doing some research and debugging my code, I've found out that there's not much differente between using DataContractJsonSerializer and JSON.Net. It's the request for the JSON data that makes response time so high `new WebClient().DownloadString(jsonURL)`, and this is necessary in both libraries. I'm trying to improve response time in this line by looking [here](http://stackoverflow.com/questions/6988981/webclient-is-very-slow), but I guess there's not much I can do – Gonzalo Apr 18 '13 at 19:12
1

The first method has the opportunity to make less copies of the data. But I have trouble believing that either method makes a measurable difference. Your real cost is going to be network costs.

Brandon
  • 38,310
  • 8
  • 82
  • 87
1

Still in an early stage but I build a code generator on top of Json.NET that eliminates reflection and speeds up deserialization by a factor of 4.

Checkout CGbR JSON target.

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

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

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

will generate a partial class:

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;
}
Toxantron
  • 2,218
  • 12
  • 23
0
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...
        }

    }
}

}

0

Out of curiosity, I've had both JSON.NET 5.0 r8 and my own (only ~ 500 lines of code) toy JSON parser eat various JSON file sizes with or without loops, from the few dozens character ballpark, to one 180 mb JSON file, of, say, "real" data.

The sample data (including a 12mb JSON but excluding the 180mb one that can be found elsewhere) with accompanying details, such as an example of parsing from a stream to deserialize into POCO (strongly typed) objects, can be found here:

https://github.com/ysharplanguage/FastJsonParser

'Hope it helps.

P.S. Good links to know about, btw, already provided by Chamika in his comment.

EDIT

Before I forget (or just in case it was overlooked), here's the kind of must-know/must-read, IMO, on the importance of not stressing the CLR's large object heap whenever possible, thanks to streamed reading of the JSON your code consumes, especially in the context of a web server environment:

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

P.P.S. (Hence the very last test in the Program.cs to test/showcase my toy parser that I linked to, above)

'HTH!

YSharp
  • 1,066
  • 9
  • 8