Net Core's next simple test of dpz2.Json and Newtonsoft.Json parsing Libraries

Keywords: ASP.NET JSON github

On dpz2.Json

dpz2.Json is a self-developed Json parsing library of Big Fatty Software.

Applied to simpler usage scenarios

Before the birth of dpz2.Json, we always used the Newtonsoft.Json parsing library. The most convenient way for Newtonsoft.Json is to use a JavaBean-like binding mode to operate, but in practice, we may want a parser more often, so that we can quickly identify the data, at this time, simple. JavaBean has become more elbow mode, reading data using the dynamic type of C # can really be more convenient to operate.

Focus on direct operation

Another important reason for us to develop a self-developed parsing library is the generation of Json statements. If we generate data classes, we can achieve the goal of rapid generation, but generating data classes for each Json will greatly increase the cost of program development.

Give a simple and typical example of Json data:

{
  aaa:{
        bbb:[111,222],
        cc:"abc"
    },
    ddd:"qaz"
}

If you use Newtonsoft.Json without generating data classes, you rely on the dynamic type of C#.

dynamic obj = new Newtonsoft.Json.Linq.JObject();
dynamic aaa = obj.aaa = new Newtonsoft.Json.Linq.JObject();
Newtonsoft.Json.Linq.JArray bbb = aaa.bbb = new Newtonsoft.Json.Linq.JArray();
bbb.Add(111);
bbb.Add(222);
aaa.cc = "abc";
obj.ddd = "qaz";
Console.WriteLine(Newtonsoft.Json.JsonConvert.SerializeObject(obj));

As you can see, if you don't know the various types under Newtonsoft.Json, it will be very headache.

If dpz2.Json is used, this problem can be effectively avoided:

using (var json = new dpz2.Json.JsonObject()) {
        var aaa = json.Object("aaa");
        var bbb = aaa.Array("bbb");
        bbb.Number(0).Value = 111;
        bbb.Number(1).Value = 222;
        aaa.String("cc").Value = "abc";
        json.String("ddd").Value = "qaz";
        Console.WriteLine(json.ToJsonString());
}

If you don't want to use intermediate variables, you can also use a direct multi-level operation (which has a very clear hierarchy, but a slightly slower operational efficiency):

using (var json = new dpz2.Json.JsonObject()) {
        json.Object("aaa").Array("bbb").Number(0).Value = 111;
        json.Object("aaa").Array("bbb").Number(1).Value = 222;
        json.Object("aaa").String("cc").Value = "abc";
        json.String("ddd").Value = "qaz";
        Console.WriteLine(json.ToJsonString());
}

In order to operate data conveniently, we provide two different operation modes: function mode and index mode: adding/accessing adaptive mode, that is, adding objects automatically if the accessed objects do not exist; and index mode is accessing mode, if the accessed objects do not exist, returning Null empty objects. .
The two modes of operation can be more freely arranged and combined. For example, the above code can be modified as follows:

using (var json = new dpz2.Json.JsonObject()) {
        json.Object("aaa").Array("bbb").Number(0).Value = 111;
        json["aaa"]["bbb"].Number(1).Value = 222;
        json["aaa"].String("cc").Value = "abc";
        json.String("ddd").Value = "qaz";
        Console.WriteLine(json.ToJsonString());
}

We provide two ways to obtain data (the two ways are equivalent, the efficiency is similar, can be used according to actual needs):

double b1 = json.Object("aaa").Array("bbb").Number(0).Value;
double b1 = json["aaa"]["bbb"][0].GetNumber();

Analysis Efficiency Comparison of dpz2.Json VS Newtonsoft.Json in Simple Environment

This test uses my own development notebook, Xiaoxinchao 7000, which is configured as i5-8250U/8G memory.

This test compares the parsing efficiency of two class libraries by parsing a long API interaction data (character length is about 1800+) and a one-time parsing plus serialization operation.

The following is the test code (compiled using Release configuration):

using System;

namespace demo {
    class Program {
        static void Main(string[] args) {

            string str = "{\"Header\":{\"Ver\":\"\",\"Type\":\"\",\"SessionID\":\"\",\"Time\":\"1565942801\",\"Status\":\"\",\"Error\":\"\"},\"Data\":{\"Apis\":[{\"Url\":\"/Api/Help/Get\",\"LoginNeed\":false,\"Controller\":\"Kernel.Api.HelpController\",\"Description\":\"API\u8f85\u52a9\u63a5\u53e3\uff0c\u8fd4\u56de\u670d\u52a1\u5668\u4e0a\u6240\u6709\u7684API\u5217\u8868\"},{\"Url\":\"/Api/Info/Update\",\"LoginNeed\":false,\"Controller\":\"Kernel.Api.InfoController\",\"Description\":\"\u83b7\u53d6\u66f4\u65b0\u65e5\u5fd7\"},{\"Url\":\"/Api/Info/Environment\",\"LoginNeed\":false,\"Controller\":\"Kernel.Api.InfoController\",\"Description\":\"\u83b7\u53d6\u8fd0\u884c\u73af\u5883\u4fe1\u606f\"},{\"Url\":\"/Api/Info/Debug\",\"LoginNeed\":false,\"Controller\":\"Kernel.Api.InfoController\",\"Description\":\"\u83b7\u53d6\u8fd0\u884c\u73af\u5883\u4fe1\u606f\"},{\"Url\":\"/Api/Info/Get\",\"LoginNeed\":false,\"Controller\":\"Kernel.Api.InfoController\",\"Description\":\"\u83b7\u53d6\u6240\u6709\u4e0e\u672c\u7a0b\u5e8f\u76f8\u5173\u7684 \u4fe1\u606f\"},{\"Url\":\"/Api/User/GetInfo\",\"LoginNeed\":false,\"Controller\":\"Kernel.Api.UserController\",\"Description\":\"\u4ee5Get\u65b9\u5f0f\u83b7 \u53d6\u767b\u9646\u7528\u6237\u4fe1\u606f\"},{\"Url\":\"/Api/User/PostInfo\",\"LoginNeed\":false,\"Controller\":\"Kernel.Api.UserController\",\"Description\":\" \u4ee5Post\u65b9\u5f0f\u83b7\u53d6\u767b\u9646\u7528\u6237\u4fe1\u606f\"},{\"Url\":\"/Api/User/Get\",\"LoginNeed\":false,\"Controller\":\"Kernel.Api.UserController\",\"Description\":\"\u9ed8\u8ba4\u4ea4\u4e92\uff0c\u8fd4\u56de\u7a7a\u5185\u5bb9\"},{\"Url\":\"/Api/Ycc/GetConfig\",\"LoginNeed\":false,\"Controller\":\"Kernel.Api.YccController\",\"Description\":\"\u83b7\u53d6\u914d\u7f6e\u4fe1\u606f\"},{\"Url\":\"/Api/Ycc/CreateNew\",\"LoginNeed\":false,\"Controller\":\"Kernel.Api.YccController\",\"Description\":\"\u521b\u5efa\u4e00\u4e2a\u4ea4\u4e92\u6807\u8bc6\"},{\"Url\":\"/Api/Ycc/Get\",\"LoginNeed\":false,\"Controller\":\"Kernel.Api.YccController\",\"Description\":\"\u9ed8\u8ba4\u4ea4\u4e92\uff0c\u8fd4\u56de\u7a7a\u5185\u5bb9\"}]}}";

            int tick0 = Environment.TickCount;

            dpz2.Json.Parser.EnforceUnicode = false;
            using (var json = dpz2.Json.Parser.ParseJson(str)) {
                Console.WriteLine(json.ToJsonString());
            }
            int tick1 = Environment.TickCount;

            dynamic dy = Newtonsoft.Json.JsonConvert.DeserializeObject(str);
            Console.WriteLine(Newtonsoft.Json.JsonConvert.SerializeObject(dy));
            int tick2 = Environment.TickCount;

            Console.WriteLine($"[dpz2.Json] {tick1 - tick0}ms");
            Console.WriteLine($"[Newtonsoft.Json] {tick2 - tick1}ms");
        }
    }
}

First run:

[dpz2.Json] 31ms
[Newtonsoft.Json] 438ms

Second operation:

[dpz2.Json] 47ms
[Newtonsoft.Json] 422ms

Third operation:

[dpz2.Json] 32ms
[Newtonsoft.Json] 422ms

The fourth operation:

[dpz2.Json] 31ms
[Newtonsoft.Json] 438ms

The fifth operation:

[dpz2.Json] 46ms
[Newtonsoft.Json] 469ms

The analytical efficiency of dpz2.Json is still satisfactory, but Newtonsoft.Json seems to be a little time-consuming. Let's see if Newtonsoft.Json can adjust the optimization parameters to make the test more valuable.

dpz2.Jso is an open source repository. You can download the source code in the following repositories:

Github: https://github.com/dpzsoft/dotnet-core-dpz2-json
Gitee: https://gitee.com/dpzsoft/dotnet-core-dpz2-json

Nuget packages are also launched synchronously:

Access address: https://www.nuget.org/packages/dotnet-core-dpz2-json/

Posted by kid_c on Fri, 16 Aug 2019 08:19:05 -0700