夸克之书

  • 首页
  • 科普
  • 笔记
  • .NET/C#
  • 物联网
  • 算法
  • Linux
  • 树莓派
夸克之内,别有洞天
  1. 首页
  2. 默认
  3. 正文

System.Text.Json与Newtonsoft.Json Json序列化与反序列化性能对比

2022-07-10 1613点热度 0人点赞 0条评论

JSON已经成为几乎所有现代.NET应用程序的重要组成部分。目前.NET处理JSON主要使用System.Text.Json和Newtonsoft.Json这两个库。

从.NET Core 3.0开始,System.Text.Json就作为内置的Json序列化与反序列化工具,以替代Newtonsoft.Json(据说Newtonsoft.Json的开发者都入职微软了)。根据微软官方描述,相对于Newtonsoft.Json,可以获得1.3倍速--5倍的速度,具体也取决于使用场景。

于是我做了个实验,来对比了下System.Text.Json和Newtonsoft.Json的序列化与反序列化的性能。顺便加入了已经弃用的二进制序列化方式。

实验方法为对同一个对象进行序列化和反序列化,反复执行100000次,取20次的平均时间。对照组有4个,分别是BinaryFormatter、System.Text.Json一般字符串序列化、System.Text.Json Utf8Bytes序列化、Newtonsoft.Json序列化。

相对Newtonsoft.Json而言,System.Text.Json序列化和反序列化更加严格,比如默认区分发大小写,不会序列化公共字段等。为了贴合日常使用场景,System.Text.Json测试方法解除了一些限制,并加入了4个常用的自定义JsonConverter类型。

System.Text.Json的JsonSerializerOptions构造方法如下:

private static JsonSerializerOptions BuildOptions(JsonSerializerOptions options)
{
    if (options == null)
    {
        lock (_locker)
        {
            if (_options == null)
            {
                _options = new JsonSerializerOptions()
                {
                    Encoder = JavaScriptEncoder.Create(UnicodeRanges.All),
                    //忽略大小写
                    PropertyNameCaseInsensitive = true,
                    //允许注释
                    ReadCommentHandling = JsonCommentHandling.Skip,
                    //允许尾随逗号
                    AllowTrailingCommas = true,
                    //允许将字符串读取为数字
                    NumberHandling = JsonNumberHandling.AllowReadingFromString,
                    //包含公共字段
                    IncludeFields = true,

                };
                _options.Converters.Add(new DateTimeConverter());
                _options.Converters.Add(new DateTimeNullableConverter());
                _options.Converters.Add(new ExceptionConverter());
                _options.Converters.Add(new TypeConverter());
            }
        }
    }
    return _options;
}

测试对象如下:

 [Serializable]
 public class SystemLog
 {
     public int Id { get; set; }

     public string LogType { get; set; }

     public string Describe { get; set; }

     public string Localtion { get; set; }

     public string Stack { get; set; }

     public DateTime CreateTime { get; set; }

     public Guid Guid { get; set; }

     public Dictionary<string, object> ExtFileds { get; set; }
 }

private static readonly SystemLog testModel = new SystemLog()
{
    Id = 1,
    LogType = "Error",
    Describe = "这个是描述,这个是描述,这个是描述,这个是描述,这个是描述",
    Stack = "",
    CreateTime = DateTime.Parse("2022-07-10"),
    Guid = Guid.NewGuid(),
    ExtFileds = new Dictionary<string, object>()
    {
        { "A", DateTime.Parse("2022-07-10")},
        { "B", "AAAAAA"},
    }
};

测试电脑环境:
CPU: i7-12700KF 3.61 GHz
内存:DDR4 3600 32G

使用包版本:

Newtonsoft.Json:13.0.1
System.Text.Json:6.0.5
.NET:6.0

测试结果如下:

%title插图%num

100000次序列化耗时:

二进制序列化:2405ms
System.Text.Json:279ms
System.Text.Json Utf8Bytes:217ms
Newtonsoft.Json:287ms

在这个场景下面,System.Text.Json比Newtonsoft.Json快了3%,System.Text.Json Utf8Bytes比Newtonsoft.Json快了24%,System.Text.Json Utf8Bytes比System.Text.Json快了0.22%。

根据测试结果,不难看出,System.Text.Json相对Newtonsoft.Json而言,确实有性能优势。特别是序列化UTF-8 字节数组时,对比更加明显, 出现这种差别的原因是字节(作为 UTF-8)不需要转换为字符串 (UTF-16)。

在进行实验时,额外加入了二进制序列化(BinaryFormatter)的对照组。结果很让人意外,BinaryFormatter在对同一对象的序列化和反序列100000次耗时2405ms,比常见的Json序列化慢了7-8倍,序列化之后的byte数组更比json通过UTF8编码后的byte数组大了6.5倍,原因是二进制序列化后的结果包含大量的元数据。

微软官方已经抛弃了BinaryFormatter ,因为二进制序列化可能会十分危险。 有关详细信息,可以参阅 BinaryFormatter 安全指南。

测试代码:

SerializeTest下载

如有任何不正确地方法,还请多多指教,大家一起交流学习。

本作品采用 知识共享署名-非商业性使用 4.0 国际许可协议 进行许可
标签: 暂无
最后更新:2023-03-20

afirefish

这个人很懒,什么都没留下

打赏 点赞
< 上一篇
下一篇 >

文章评论

您需要 登录 之后才可以评论
放松一下
https://www.quarkbook.com/wp-content/uploads/2021/05/凤凰传奇-海底(Live).flac
分类
  • .NET/C#
  • Linux
  • 树莓派
  • 物联网
  • 科普
  • 笔记
  • 算法
  • 默认
最新 热点 随机
最新 热点 随机
维持宇宙的四种“力量”——关于四大基本力 MinGW图形安装界面里面没有mingw32 make.exe解决办法 Windows Server 2022安装Intel I225-V/I226-V驱动 System.Text.Json与Newtonsoft.Json Json序列化与反序列化性能对比 R86S散热改造 Windows移除多余输入法'Unknown Locale (qaa-Latn)'
Windows Server 2022安装Intel I225-V/I226-V驱动MinGW图形安装界面里面没有mingw32 make.exe解决办法维持宇宙的四种“力量”——关于四大基本力
C#中抽象类(abstract)和接口(interface)的相同点与区别 Visual Studio调试时不中断自定义异常 PostgreSQL重置所有表Sequence 简单开始异步编程(1) 安装ESP8266的Arduino开发环境 在.NET 6中System.Drawing.Common引发的“The type initializer for 'Gdip' threw an exception.”异常
最近评论
afirefish 发布于 4 个月前(11月28日) 非常感谢,非常棒!
》随缘《 发布于 4 个月前(11月20日) 最新【一键处理】方法: https://github.com/MrXhh/VSTools/rele...
管理员 发布于 9 个月前(06月22日) emmmm....服务器好一点???
wking 发布于 10 个月前(05月23日) 请问贵博客是怎么优化的,网页响应速度非常快。我博客同样的WordPress和kratos主题,但点一...
去月球 发布于 1 年前(01月17日) 如果使用CSI的摄像头应该怎么修改命令呢
书签
  • 打赏
  • 毒鸡汤
  • 米店
  • 金鱼直播间

COPYRIGHT © 2022 quarkbook.com. ALL RIGHTS RESERVED.

Theme Kratos Made By Seaton Jiang

蜀ICP备15036129号-9

登录
注册|忘记密码?