.NET性能系列文章二:Newtonsoft.Json vs System.Text.Json

微软终于追上了?

7523af1d1b01bca292e0627bcbe1fef4.jpeg

图片来自 Glenn Carstens-Peters[1]Unsplash[2]

欢迎来到.NET 性能系列的另一章。这个系列的特点是对.NET 世界中许多不同的主题进行研究、基准和比较。正如标题所说的那样,重点在于使用最新的.NET7 的性能。你将看到哪种方法是实现特定主题的最快方法,以及大量的技巧和窍门,你如何能以较低的努力最大化你的代码性能。如果你对这些主题感兴趣,请继续关注

在这篇文章中,我们将比较两个最突出的.NET 的 json 框架。:Newtonsofts Json.NET[3] 和 Microsofts System.Text.Json[4].

Newtonsoft.Json是 NuGet 上下载量最大的软件包,下载量超过23 亿System.Text.Json稍稍落后,大约有6 亿次下载。然而,我们需要考虑的是,System.Text.Json自.NET Core 3.1 起就默认随.NET SDK 交付。既然如此,Newtonsoft 似乎仍然是最受欢迎的 json 框架。让我们来看看,它是否能保持它的名次,或者微软是否在性能方面缓慢但肯定地领先。

测试方案

为了模拟现实生活中应用的真实场景,我们将测试两个主要用例。

  • 第一,单个大数据集的序列化和反序列化。

  • 第二是许多小数据集的序列化和反序列化。

一个真实的场景也需要真实的数据。对于测试数据集,我决定使用 NuGet 包Bogus[5]。通过 Bogus,我能够快速生成许多不同的用户,包括个人姓名、电子邮件、ID 等。

[Params(10000)]
public int Count { get; set; }private List<User> testUsers;[GlobalSetup]
public void GlobalSetup()
{var faker = new Faker<User>().CustomInstantiator(f => new User(Guid.NewGuid(),f.Name.FirstName(),f.Name.LastName(),f.Name.FullName(),f.Internet.UserName(f.Name.FirstName(), f.Name.LastName()),f.Internet.Email(f.Name.FirstName(), f.Name.LastName())));testUsers = faker.Generate(Count);
}

对于基准,我们将使用每个软件包的最新版本,目前是(2022 年 10 月):

  • Newtonsoft.Json — 13.0.1 and

  • System.Text.Json — 7.0.0-rc.2[6]

序列化测试

序列化大对象

为了测试一个大对象的序列化,我们简单地使用List<User>,我们在GlobalSetup()方法中设置了它。我们的基准方法看起来像这样:

[Benchmark(Baseline = true)]
public void NewtonsoftSerializeBigData() =>_ = Newtonsoft.Json.JsonConvert.SerializeObject(testUsers);[Benchmark]
public void MicrosoftSerializeBigData() =>_ = System.Text.Json.JsonSerializer.Serialize(testUsers);

这些方法都使用默认的ContractResolver,它只被实例化一次,因此是两个框架中性能最好的序列化选项。如果你使用自定义的JsonSerializerSettings,注意不要多次实例化ContractResolver,否则你会降低很多性能。

现在我们来看看结果:

MethodCountMeanRatioAllocatedAlloc Ratio
NewtonsoftSerializeBigData100007.609 ms1.008.09 MB1.00
MicrosoftSerializeBigData100003.712 ms0.493.42 MB0.42
9fe0674c658e42905e7af106b0830481.png

尽管 Newtonsoft 在他们的第一个文档网站[7]上说。

高性能:比.NET 的内置 JSON 序列化器快

我们可以清楚地看到,到目前为止,他们并不比内置的 JSON 序列化器快。至少在这个用例中是这样。让我们来看看,在其他使用情况下是否也是如此。

序列化许多小对象

这个用例在实际应用中比较常见,例如在 REST-Apis 中,每个网络请求都必须处理 JSON 序列化数据,并且也要用 JSON 序列化数据进行响应。

为了实现这个用例,我们使用之前建立的List<User>,并简单地循环通过它,同时单独序列化每个用户。

[Benchmark(Baseline = true)]
public void NewtonsoftSerializeMuchData()
{foreach (var user in testUsers){_ = Newtonsoft.Json.JsonConvert.SerializeObject(user);}
}[Benchmark]
public void MicrosoftSerializeMuchData()
{foreach (var user in testUsers){_ = System.Text.Json.JsonSerializer.Serialize(user);}
}

在我的机器上,这个基准测试导致了以下结果:

MethodCountMeanRatioAllocatedAlloc Ratio
NewtonsoftSerializeMuchData100008.087 ms1.0017.14 MB1.00
MicrosoftSerializeMuchData100003.944 ms0.493.64 MB0.21
4befa293ede13f468f8d39ff2fddfe47.png

我们可以看到对于许多小对象来说,性能又快了近 100%。不仅 System.Text.Json 的性能比 Newtonsoft 快了一倍,而且堆分配的内存甚至少了 5 倍! 正如我在以前的文章中提到的,节省堆内存甚至比速度更重要,你在这里看到了。堆内存最终将不得不被垃圾回收,这将阻塞你的整个应用程序的执行。

反序列化测试

在现实世界的应用中,你不仅要序列化,还要从 JSON 序列化的字符串中反序列化对象。在下面的基准中,我们将再次使用 Bogus,创建一组用户,但这次我们要把它们序列化为一个大的字符串,用于大数据对象,并把许多小数据对象序列化为List<string>

private string serializedTestUsers;private List<string> serializedTestUsersList = new();[GlobalSetup]
public void GlobalSetup()
{var faker = new Faker<User>().CustomInstantiator(f => new User(Guid.NewGuid(),f.Name.FirstName(),f.Name.LastName(),f.Name.FullName(),f.Internet.UserName(f.Name.FirstName(), f.Name.LastName()),f.Internet.Email(f.Name.FirstName(), f.Name.LastName())));var testUsers = faker.Generate(Count);serializedTestUsers = JsonSerializer.Serialize(testUsers);foreach (var user in testUsers.Select(u => JsonSerializer.Serialize(u))){serializedTestUsersList.Add(user);}
}

反序列化大对象

第一个反序列化基准将一个大的 JSON 字符串反序列化为相应的.NET 对象。在这种情况下,它又是List<User>,我们在前面的例子中也使用了它。

[Benchmark(Baseline = true)]
public void NewtonsoftDeserializeBigData() =>_ = Newtonsoft.Json.JsonConvert.DeserializeObject<List<User>>(serializedTestUsers);[Benchmark]
public void MicrosoftDeserializeBigData() =>_ = System.Text.Json.JsonSerializer.Deserialize<List<User>>(serializedTestUsers);

在我的机器上运行这些基准测试,得出以下结果:

MethodCountMeanRatioAllocatedAlloc Ratio
NewtonsoftDeserializeBigData1000021.20 ms1.0010.55 MB1.00
MicrosoftDeserializeBigData1000012.12 ms0.576.17 MB0.59
b4bfb30e30af705e7b1b154f1babd374.png

就性能而言,微软仍然远远领先于 Newtonsoft。然而,我们可以看到,Newtonsoft 并没有慢一半,而是慢了 40%左右,这在与序列化基准的直接比较中是一个进步。

反序列化许多小对象

本章的最后一个基准是许多小对象的反序列化。在这里,我们使用我们在上面的GlobalSetup()方法中初始化的List<string>,在一个循环中反序列化数据对象:

[Benchmark(Baseline = true)]
public void NewtonsoftDeserializeMuchData()
{foreach (var user in serializedTestUsersList){_ = Newtonsoft.Json.JsonConvert.DeserializeObject<User>(user);}
}[Benchmark]
public void MicrosoftDeserializeMuchData()
{foreach (var user in serializedTestUsersList){_ = System.Text.Json.JsonSerializer.Deserialize<User>(user);}
}

其结果甚至比相关的序列化基准更令人吃惊:

MethodCountMeanRatioAllocatedAlloc Ratio
NewtonsoftDeserializeMuchData1000015.577 ms1.0035.54 MB1.00
MicrosoftDeserializeMuchData100007.916 ms0.514.8 MB0.14
770220a0ae437388b118652907db3598.png

在 Microsofts 框架下,速度又快了一倍,内存效率是惊人的7倍,比 Newtonsoft 还要好!

总结

尽管 Newtonsoft 在他们的文档[8]上说:

高性能:比.NET 的内置 JSON 序列化器更快

很明显,至少从.NET 7 开始,Microsofts 的System.Text.Json在所有测试的用例中至少快了一倍,命名为。

  • 序列化一个大数据集

  • 序列化许多小数据集

  • 对一个大数据集进行反序列化

  • 对许多小数据集进行反序列化

所有这些都是在每个框架的默认序列化器设置下进行的。

不仅速度快了 100%,而且在某些情况下,分配的内存甚至比 Newtonsoft 的效率高 5 倍以上。

我甚至认为,可以推断出结果,目前使用System.Text.JsonNewtonsoft.Json更快。

请记住,这些结果只对最新的.NET 7 有效。如果你使用的是其他版本的.NET,情况可能正好相反,Newtonsoft 可能会更快。

我希望,我的文章可以帮助你对序列化器做出选择选择,并让你对性能和基准测试的世界有一个有趣的切入点。

如果你喜欢这个系列的文章,请一定要关注我,因为还有很多有趣的话题等着你。

谢谢你的阅读!

版权

原文版权:Tobias Streng
翻译版权:InCerry

原文链接:https://medium.com/@tobias.streng/net-performance-series-2-newtonsoft-vs-system-text-json-2bf43e037db0

参考资料

[1]

Glenn Carstens-Peters: https://unsplash.com/@glenncarstenspeters?utm_source=medium&utm_medium=referral

[2]

Unsplash: https://unsplash.com/?utm_source=medium&utm_medium=referral

[3]

Newtonsofts Json.NET: https://www.newtonsoft.com/json

[4]

Microsofts System.Text.Json: https://www.nuget.org/packages/System.Text.Json

[5]

Bogus: https://github.com/bchavez/Bogus

[6]

7.0.0-rc.2: https://www.nuget.org/packages/System.Text.Json/7.0.0-rc.2.22472.3

[7]

第一个文档网站: https://www.newtonsoft.com/json/help/html/Introduction.htm

[8]

文档: https://www.newtonsoft.com/json/help/html/Introduction.htm

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/281512.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

android gpu平板 推荐,性能强的不像话,最强安卓平板华为平板M6上手

原标题&#xff1a;性能强的不像话&#xff0c;最强安卓平板华为平板M6上手你为什么买平板电脑&#xff1f;当这一问题问出以后&#xff0c;许多朋友的表情都很微妙&#xff0c;随后大概率的回答则相当统一&#xff1a;"我买平板干嘛&#xff1f;"。其实得到这样一个…

【Python】HackBack(获取暴力破解服务器密码的IP来源)

1、前言 又在0x00sec上翻到好东东。 https://0x00sec.org/t/python-hackback-updated/882 帖子里的脚本会得到那些暴力服务器密码失败的IP和用户名&#xff0c;并且使用shodan api做一个溯源定位。 #!/usr/bin/python3.4 import re import urllib.request import json log_path…

企业应用“数据优先”革命的下一个主战场:安全与运营

根据IDC发布的2015年全球CIO日程预测&#xff0c;80%的CIO将提供一个实现创新和改善业务决策的新体系架构。 大数据时代&#xff0c;企业软件市场正在经历一次大迁移&#xff0c;数以十亿计的企业IT支出预算将投向“数据优先”应用&#xff0c;而不是长久以来以业务流程和工作流…

给Web开发人员的以太坊入坑指南

以太坊现在各种学习资料数不胜数&#xff0c;但由于以太坊正处于飞速发展阶段&#xff0c;有些学习资料很快就过时了。所以想找到有价值的资料无异于大海捞针。我费了很大功夫&#xff0c;才建立起对以太坊的整体认识&#xff0c;搞清楚它的工作机制。我相信很多跃跃欲试的开发…

和硕看重物联网大势 程建中:从擅长领域出发

物联网(IoT)前景可期已是全球科技产业的共识&#xff0c;但是如何真正找出到位的商机&#xff0c;却考验产业链业者的智能。苹果iPhone代工厂和硕联合科技执行长程建中表示&#xff0c;物联网与大数据相关应用商机看俏&#xff0c;物联网筑的梦比网际网路还大&#xff0c;当年网…

html选择文本框后提示消失,两种方法实现文本框输入内容提示消失

第一种方法&#xff1a;基于HTML5 input标签的新特性 - placeholder 。另外&#xff0c;x-webkit-speech 属性可以实现语音输入功能。第二种方法&#xff1a;用span模拟&#xff0c;定位span&#xff0c;借助JS键盘事件判断输入&#xff0c;确定span里的内容显示隐藏。无标题文…

TensorFlow基本计算单元——变量

# -*- coding: utf-8 -*- import tensorflow as tf a 3 # 创建变量 w tf.Variable([[0.5, 1.0]]) #行向量 x tf.Variable([[2.0], [1.0]]) y tf.matmul(w, x) #矩阵相乘 print(y) # Tensor("MatMul:0", shape(1, 1), dtypefloat32)init_op tf.global_variables…

程序人生:织梦dedecms后台/会员验证码关闭

dedecms默认是所有的功能几乎只要用到验证码的地方我们都需要验证的&#xff0c;如果要关闭一些验证功能我们可以参考下面的教程&#xff0c;这里介绍了关闭后台&#xff0c;留言板&#xff0c;会员系统等验证码功能关闭了。提示&#xff1a;支持DedeCMS V5.6 以上的所有版本取…

html中图片的属性优化,Html标签元素在SEO中的优化方式(二)

接上html标签元素在SEO中的优化方式(一)中对HTML界面的介绍&#xff0c;我们今天继续补充HTML标签的SEO优化方式在内容中有几个值得去研究一下的优化元素--导航和内部链接&#xff1a;很明显的一点&#xff0c;建立导航会使搜索引擎可以容易的确定网站结构&#xff0c;但是很多…

Gartner认为安全性将取代成本和敏捷性成为政府部门采用云服务的首要原因

全球领先的信息技术研究和顾问公司Gartner表示&#xff0c;公有云如今具备可扩展性、计算威力、海量存储和安全性&#xff0c;可打造更好的政府数字化平台并满足对业绩和价值不断增长的期望值。 Gartner预计到2018年&#xff0c;提升的安全性将取代成本节约和敏捷性成为政府部门…

一款简单的缩放拖拽图片控件

本文介绍一个针对 .NET 桌面应用程序的独立图片缩放拖拽显示控件 SQPhoto[1]。SQPhoto 是一个 Windows 桌面应用的组件&#xff0c;支持 .NET6 和 .NET Framework 4.6 。基于 PictureBox 的图片展示工具&#xff0c;增加了拖动和缩放功能&#xff0c;便于在某些场景下的图片展…

安卓虚拟机与Hyper-V冲突

经过各种经验&#xff0c;哪个安卓虚拟机跟Hyper-V都存在着冲突。 解决方案一 程序中卸载Hyper-V&#xff0c;之后还要再配置太麻烦。 解决方案二 1、关掉Hyper-V的启动项&#xff0c;命令如下。 bcdedit /set hypervisorlaunchtype off 重启在开安卓模拟器蓝屏就没有了。 2、重…

共轨之家获吉利家族基金新一轮融资 5个月前曾获磐霖资本领投A轮融资

11月27日消息&#xff0c;近日&#xff0c;国内最大商用车技术服务平台共轨之家对外宣布完成新一轮融资。本轮融资由吉利家族基金投资&#xff0c;未来将推进共轨之家占领商用车后市场。 成立于2014年的共轨之家&#xff0c;以商用车技术知识科普社区起家&#xff0c;积累起国…

光伏产业的发展推动太阳能组件技术进步

从全球能源发展趋势的角度来看&#xff0c;太阳能等可再生能源势必逐步替代不可再生的传统能源&#xff0c;光伏产业将在全球各国的经济发展中扮演重要的角色。大力开发和利用光伏产业&#xff0c;对于优化我国能源结构&#xff0c;优化环境&#xff0c;保证我国社会经济可持续…

HTML怎么让div全透明,设置div为透明 怎样才让div里面的div不透明?

#a{ background:#FFCC33; filter:alpha(opacity:0); width: 300px; heig#a{background:#FFCC33; filter:alpha(opacity50); /*支持 IE 浏览器*/-moz-opacity:0.50; /*支持 FireFox 浏览器*/opacity:0.50; /*支持 Chrome, Opera, Safari 等浏览器*/width: 300px;height:300px;}还…

k64 datasheet学习笔记12---System Integration Module (SIM)

1.前言 Features of the SIM include: System clocking configuration&#xff08;1&#xff09;System clock divide values&#xff08;2&#xff09; Architectural clock gating control&#xff08;3&#xff09; USB clock selection and divide values&#xff08;4&…

informix linux安装步骤

informix linux安装步骤整个安装过程都以root用户运行1. 创建informix用户# groupadd informix# useradd -g informix informix2. 创建安装目录: "/opt/informix"# mkdir /opt/informix# chown informix.informix /opt/informixyum install libc.so.6 libncurses.so.…

html overflow 样式,css样式之overflow-x属性样式

overflow-x是overflow子花样&#xff0c;平日也很少用的。overflow-x设置匿伏溢出过宽模式(比如过宽图片)、设置对象底部转折条等重要。overflow-x语法与根本懂得1、overflow-x可设置值overflow-x : visible | auto | hidden| scroll值与解释引见&#xff1a;visible :  不剪切…

泰国能源部携手本土企业打造智慧城市

泰国能源部与泰国安美德集团签署谅解备忘录&#xff0c;共同投资开发新能源在工业生产领域的应用。俞懿春 摄 泰国能源部与泰国安美德&#xff08;AMATA&#xff09;集团昨天在曼谷签署谅解备忘录&#xff0c;以公私合作模式推动安美德智慧城市开发&#xff0c;响应泰国政府提出…

MAMP升级mysql5.6到5.7

RT 1.先把mamp环境停掉 sudo sh /Applications/MAMP/bin/stop.sh 2.然后使用brew安装mysql5.7 brew install mysql 3.默认安装的是最新版本&#xff0c;因为是5.7所以要手动设置一下root用户的密码,跟着步骤设置就行 /usr/local/Cellar/mysql/5.7.20/bin sudo ./mysql_secure_…