zoukankan      html  css  js  c++  java
  • C#.Net 使用 JsonReader/JsonWriter 高性能解析/生成 Json 文档

      Swifter.Json 是由本人编写的高性能且多功能的 Json 解析库。下图是 Swifter.Json 与 .Net 平台上的其他 Json 库性能对比:

      

      在 Swifter.Json 近期更新的 API 中增加了直接构建 JSON 和直接解析 JSON 的方法。下面演示这两个方法如何使用:

      1:使用 JsonWriter 直接生成 Json 文档:

    using Swifter.Json;
    using Swifter.Tools;
    using System;
    
    public class Demo
    {
        public static void Main()
        {
            var jsonWriter = JsonFormatter.CreateJsonWriter();
    
            jsonWriter.WriteBeginObject();
    
            jsonWriter.WritePropertyName("Id");
            jsonWriter.WriteInt32(123);
    
            jsonWriter.WritePropertyName("Name");
            jsonWriter.WriteString("Dogwei");
    
            jsonWriter.WriteEndObject();
    
            Console.WriteLine(jsonWriter.HGCache.ToStringEx());
    
    
    
            /**
             * Output : {"Id":123,"Name":"Dogwei"}
             */
        }
    }

      注意:使用 JsonWriter 时应将 jsonWriter 保存起来,重复使用,这样才能将性能最大化。

      2:使用 JsonReader 直接遍历 Json 文档:

    using Swifter.Json;
    using System;
    using System.IO;
    
    public class Demo
    {
        public static void Main()
        {
            using var textReader = new StringReader("{"Id":123,"Name":"Dogwei"}");
    
            var jsonReader = JsonFormatter.CreateJsonReader(textReader);
    
            if (jsonReader.TryReadBeginObject())
            {
                while (!jsonReader.TryReadEndObject())
                {
                    var name = jsonReader.ReadPropertyName();
    
                    switch (name)
                    {
                        case "Id":
                            Console.WriteLine($"{name}: {jsonReader.ReadInt32()}");
                            break;
                        case "Name":
                            Console.WriteLine($"{name}: {jsonReader.ReadString()}");
                            break;
                        default:
                            Console.WriteLine($"{name}: {jsonReader.DirectRead()}");
                            break;
                    }
                }
            }
    
            /** 
             * Output : 
             * Id: 123
             * Name: Dogwei
             */
        }
    }

      3:更简单的遍历 Json 文档:

    using Swifter.Json;
    using System;
    using System.IO;
    
    public class Demo
    {
        public static void Main()
        {
            using var textReader = new StringReader("[{"Id":1,"Name":"Dogwei"},{"Id":2,"Name":"ChenXinwei"},{"Id":3,"Name":"Swifter.Json"}]");
    
            var jsonReader = JsonFormatter.CreateJsonReader(textReader);
    
            foreach (var item in jsonReader.ReadArray())
            {
                foreach (var pair in item.ReadObject())
                {
                    var name = pair.Key;
                    var value = pair.Value.DirectRead();
    
                    Console.WriteLine($"{name} : {value}");
                }
            }
    
            /** 
             * Output : 
             * Id : 1
             * Name : Dogwei
             * Id : 2
             * Name : ChenXinwei
             * Id : 3
             * Name : Swifter.Json
             */
        }
    }

      注意:JsonReader 是原始提供的是原始解析 Json 的方法,它性能极快,也正因此,它每个读取方法都会偏移游标,不读取就不偏移,解析 Json 时所有的 '值' 都必须读且只读一次!如上例:如果 pair.Value.DirectRead() 调用了两次,或者一次都没调用,那么就会解析出错!

      下例做一下简单的性能对比:

    using Newtonsoft.Json;
    using Swifter.Json;
    using System;
    using System.Diagnostics;
    using System.IO;
    
    public class Demo
    {
        public static void Main()
        {
            var swifterWriter = JsonFormatter.CreateJsonWriter();
    
            var newtonsoftStringWriter = new StringWriter();
            var newtonsoftWriter = new JsonTextWriter(newtonsoftStringWriter);
    
            while (true)
            {
                var stopwatch = Stopwatch.StartNew();
    
                for (int i = 0; i < 1000000; i++)
                {
                    newtonsoftWriter.WriteStartObject();
    
                    newtonsoftWriter.WritePropertyName("Id");
                    newtonsoftWriter.WriteValue(123);
    
                    newtonsoftWriter.WritePropertyName("Name");
                    newtonsoftWriter.WriteValue("Dogwei");
    
                    newtonsoftWriter.WriteEndObject();
    
                    newtonsoftStringWriter.GetStringBuilder().Length = 0;
                }
    
                Console.WriteLine($"Newtonsoft.Json : {stopwatch.ElapsedMilliseconds}");
    
                stopwatch = Stopwatch.StartNew();
    
                for (int i = 0; i < 1000000; i++)
                {
                    swifterWriter.WriteBeginObject();
    
                    swifterWriter.WritePropertyName("Id");
                    swifterWriter.WriteInt32(123);
    
                    swifterWriter.WritePropertyName("Name");
                    swifterWriter.WriteString("Dogwei");
    
                    swifterWriter.WriteEndObject();
    
                    swifterWriter.Clear();
                }
    
                Console.WriteLine($"Swifter.Json : {stopwatch.ElapsedMilliseconds}");
    
                Console.ReadKey();
            }
    
            /**
             * Output:
             * Newtonsoft.Json : 197
             * Swifter.Json : 64
             */
        }
    }
    using Newtonsoft.Json;
    using Swifter.Json;
    using System;
    using System.Diagnostics;
    using System.IO;
    
    public class Demo
    {
        public static void Main()
        {
            while (true)
            {
                var stopwatch = Stopwatch.StartNew();
    
                for (int i = 0; i < 1000000; i++)
                {
                    var jsonReader = new JsonTextReader(new StringReader("{"Id":123,"Name":"Dogwei"}"));
    
                    while (jsonReader.Read())
                    {
                        if (jsonReader.TokenType == JsonToken.PropertyName)
                        {
                            var name = (string)jsonReader.Value;
    
                            switch (name)
                            {
                                case "Id":
                                    jsonReader.ReadAsInt32();
                                    break;
                                case "Name":
                                    jsonReader.ReadAsString();
                                    break;
                                default:
                                    jsonReader.Skip();
                                    break;
                            }
                        }
                    }
                }
    
                Console.WriteLine($"Newtonsoft.Json : {stopwatch.ElapsedMilliseconds}");
    
                stopwatch = Stopwatch.StartNew();
    
                for (int i = 0; i < 1000000; i++)
                {
                    var jsonReader = JsonFormatter.CreateJsonReader(new StringReader("{"Id":123,"Name":"Dogwei"}"));
    
                    if (jsonReader.TryReadBeginObject())
                    {
                        while (!jsonReader.TryReadEndObject())
                        {
                            var name = jsonReader.ReadPropertyName();
    
                            switch (name)
                            {
                                case "Id":
                                    jsonReader.ReadInt32();
                                    break;
                                case "Name":
                                    jsonReader.ReadString();
                                    break;
                                default:
                                    jsonReader.SkipValue();
                                    break;
                            }
                        }
                    }
                }
    
                Console.WriteLine($"Swifter.Json : {stopwatch.ElapsedMilliseconds}");
    
                Console.ReadKey();
            }
    
            /**
             * Output:
             * Newtonsoft.Json : 759
             * Swifter.Json : 161
             */
        }
    }

      特别强调:这两种方式都是提供给有特别需求的用户,普通用户不建议使用,因为使用门槛较高,不利于维护!个人建议是定义模型,然后不管是序列化和反序列化都使用模型!这样在保证性能的情况下,使用也变得简单,易于维护。

      最后附上 Swifter.Json 的开源地址:https://github.com/Dogwei/Swifter.Json 希望大家支持一下。

  • 相关阅读:
    关于loose.dtd和xhtml1transitional.dtd等文档类型定义模型中CSS失效的解决办法。
    JSON扫盲帖+JSON类教程
    jQuery中Ajax事件
    JQuery绑定事件 时如何传递参数
    xml include 另外一个xml文件
    ubuntu 两张网卡时网络设置
    Letcode 题:pow(x,n)
    Java编程语言中sleep()和yield()的区别
    JProfiler与eclipse集成
    zz 字符串相关
  • 原文地址:https://www.cnblogs.com/Dogwei/p/11238941.html
Copyright © 2011-2022 走看看