C#中 Json序列化与反序列的几种方法

一、System.Text.Json(微软自带)

      #region using System.Text.Json
      private static string ObjectToStringOne(Object obj)
      {
          string str = System.Text.Json.JsonSerializer.Serialize(obj);
          return str;
      }
      private static T StringToObjectOne<T>(string str)
      {
          T obj = System.Text.Json.JsonSerializer.Deserialize<T>(str);
          return obj;
      }
      #endregion

二、NewTonsoft.Json(包)

      #region using NewTonsoft.Json
      private static string ObjectToStringTwo(Object obj)
      {
          string str = Newtonsoft.Json.JsonConvert.SerializeObject(obj);
          return str;
      }

      private static T StringToObjectTwo<T>(string str)
      {
          T obj = Newtonsoft.Json.JsonConvert.DeserializeObject<T>(str);
          return obj;
      }
      #endregion

三、System.Runtime.Serialization.Json(以数据流为中介)

     #region using System.Runtime.Serialization.Json;
     private static string ObjectToStringThree<T>(Object obj)
     {
         // Object->stream->string
         DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(T));
         MemoryStream ms = new MemoryStream();
         serializer.WriteObject(ms, obj);

         ms.Position = 0;
         StreamReader sr = new StreamReader(ms, Encoding.UTF8);
         string content_josn = sr.ReadToEnd();
         sr.Close();

         return content_josn;
     }
     private static T StringToObjectThree<T>(string str)
     {
         // string->stream->Object
         using (MemoryStream ms2 = new MemoryStream(Encoding.Unicode.GetBytes(str)))
         {
             DataContractJsonSerializer deserializer = new DataContractJsonSerializer(typeof(T));
             T obj = (T)deserializer.ReadObject(ms2);
             return obj;
         }
     }
     #endregion

四、Nancy(包)

     #region using Nancy.Json;
     private static string ObjectToStringFour(Object obj)
     {
         JavaScriptSerializer jss = new JavaScriptSerializer();
         return jss.Serialize(obj);
     }
     private static T StringToObjectFour<T>(string str)
     {
         JavaScriptSerializer jss = new JavaScriptSerializer();
         return jss.Deserialize<T>(str);
     }
     #endregion

五、性能测试

1、使用Bogus生成假数据

	// 生成类
   	[DataContract]
    internal class Person
    {
        [DataMember]
        public Guid Id { get; set; }
        [DataMember]
        public string Name { get; set; }
        [DataMember]
        public string Address { get; set; }
        [DataMember]
        public string Email { get; set; }
    }

	 // Nuget下载Bogus包,引用命名空间,使用Faker创建假数据生成器
     var studentgenerator = new Faker<Person>()
         .RuleFor(o => o.Id, Guid.NewGuid)
         .RuleFor(o => o.Name, f => f.Person.UserName)
         .RuleFor(o => o.Address, f => f.Person.Address.City)
         .RuleFor(o => o.Email, f => f.Person.Email);
     var studentlist = studentgenerator.Generate(100000);

2、序列与反序列单个大对象

	Stopwatch sw = new Stopwatch();
    string str;

    // 微软自带System.Text.Json
    sw.Start();
    str = ObjectToStringOne(studentlist);
    StringToObjectOne<List<Person>>(str);
    sw.Stop();
    Console.WriteLine($"{sw.ElapsedTicks}");

    // Newtonsoft.Json包
    sw.Reset();
    sw.Start();
    str = ObjectToStringTwo(studentlist);
    StringToObjectTwo<List<Person>>(str);
    sw.Stop();
    Console.WriteLine($"{sw.ElapsedTicks}");

    // 数据流System.Runtime.Serialization.Json
    sw.Reset();
    sw.Start();
    str = ObjectToStringThree<List<Person>>(studentlist);
    StringToObjectThree<List<Person>>(str);
    sw.Stop();
    Console.WriteLine($"{sw.ElapsedTicks}");

    // Nancy包
    sw.Reset();
    sw.Start();
    str = ObjectToStringFour(studentlist);
    StringToObjectFour<List<Person>>(str);
    sw.Stop();
    Console.WriteLine($"{sw.ElapsedTicks}");

3、序列与反序列多个小对象

    Stopwatch sw = new Stopwatch();
    string str;
    
    // 微软自带System.Text.Json
    sw.Start();
    foreach(var item in studentlist)
    {
        str = ObjectToStringOne(item);
        StringToObjectOne<Person>(str);
    }
    sw.Stop();
    Console.WriteLine($"{sw.ElapsedTicks}");

    // Newtonsoft.Json包
    sw.Reset();
    sw.Start();
    foreach (var item in studentlist)
    {
        str = ObjectToStringTwo(item);
        StringToObjectTwo<Person>(str);
    }
    sw.Stop();
    Console.WriteLine($"{sw.ElapsedTicks}");

    // 数据流System.Runtime.Serialization.Json
    sw.Reset();
    sw.Start();
    foreach (var item in studentlist)
    {
        str = ObjectToStringThree<Person>(item);
        StringToObjectThree<Person>(str);
    }
    sw.Stop();
    Console.WriteLine($"{sw.ElapsedTicks}");

    // Nancy包
    sw.Reset();
    sw.Start();
    foreach (var item in studentlist)
    {
        str = ObjectToStringFour(item);
        StringToObjectFour<Person>(str);
    }
    sw.Stop();
    Console.WriteLine($"{sw.ElapsedTicks}");

六、测试结果

1. 测试版本

方法版本
1.Net Core 3.1
213.0.2
3.Net Core 3.1
42.0.0

2. 结果

类数量序列与反序列单个大对象序列与反序列多个小对象
10004>3>1>22>3>4>1
100001>3>4>22>4=3>1
1000001>3>2>42>3>4>1

3.结论

对应的数据代表方法名,越大代表性能越好用时越短

  1. 在序列与反序列多个小对象的场景下,1方法性能最差,2方法性能最好。
  2. 在序列与反序列多单个大对象的场景下,对象越大,1方法的性能优势越明显,其次是3方法。
  3. 具体使用哪种方法要根据应用场景的对象大小和使用频率决定。

七、参考文章

1.测试方案参考

2.序列化方式参考1

3.序列化方式参考2

4.测试结果参考

5.假数据生成器

6.Bogus的使用方法

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值