.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;"。其实得到这样一个…

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

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

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

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

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

本文介绍一个针对 .NET 桌面应用程序的独立图片缩放拖拽显示控件 SQPhoto[1]。SQPhoto 是一个 Windows 桌面应用的组件&#xff0c;支持 .NET6 和 .NET Framework 4.6 。基于 PictureBox 的图片展示工具&#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;}还…

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

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

C# WPF GridControl用法举例

概述GridControl是Dev中的表格控件&#xff0c;类似于Winfrom中的DataGridView&#xff0c;以及WPF中的DataGrid&#xff0c;但是这个控件功能比原生的功能要强大很多&#xff0c;下面用实例举例说明此控件的用法.代码前台XAML&#xff1a;<UserControl x:Class"Calibu…

js中关于Blob对象的介绍与使用

js中关于Blob对象的介绍与使用 blob对象介绍 一个 Blob对象表示一个不可变的, 原始数据的类似文件对象。Blob表示的数据不一定是一个JavaScript原生格式 blob对象本质上是js中的一个对象&#xff0c;里面可以储存大量的二进制编码格式的数据。 创建blob对象 创建blob对象本质上…

20170102-文件处理

文件处理 正常文件处理 python 文件处理 编码 f open(file"兼职白领学生空姐模特护士练习方式.txt",mode"r",encoding"utf-8")#把值附给变量f &#xff08;路径file"文件是兼职白领学生空姐模特护士练习方式.txt"&#xff0c;文本模式…

创建.NET程序Dump的几种姿势

当一个应用程序运行的有问题时&#xff0c;生成一个 Dump 文件来调试它可能会很有用。在 Windows、Linux 或 Azure 上有许多方法可以生成转储文件。Windows 平台dotnet-dump (Windows)dotnet-dump 全局工具[1]是一种收集和分析.NET 核心应用程序 Dump 的方法。安装 dotnet-dump…

自然语言处理怎么最快入门?

2019独角兽企业重金招聘Python工程师标准>>> 本文整理自知乎上的一个问答&#xff0c;分享给正在学习自然然语言处理的朋友们&#xff01; 一、自然语言处理是什么&#xff1f; 自然语言处理说白了&#xff0c;就是让机器去帮助我们完成一些语言层面的事情&#xff…

dotnet-exec 0.8.0 released

dotnet-exec 0.8.0 releasedIntrodotnet-exec 是一个 C# 程序的小工具&#xff0c;可以用来运行一些简单的 C# 程序而无需创建项目文件&#xff0c;而且可以自定义项目的入口方法&#xff0c;支持但不限于 Main 方法Install/Updatedotnet-exec 是一个 dotnet tool&#xff0c;可…

Siamese Network理解

提起siamese network一般都会引用这两篇文章&#xff1a; 《Learning a similarity metric discriminatively, with application to face verification》和《 Hamming Distance Metric Learning》。 本文主要通过论文《Learning a Similarity Metric Discriminatively, with A…

HashMap是如何工作的

2019独角兽企业重金招聘Python工程师标准>>> 1 HashMap在JAVA中的怎么工作的&#xff1f; 基于Hash的原理 2 什么是哈希&#xff1f; 最简单形式的 hash&#xff0c;是一种在对任何变量/对象的属性应用任何公式/算法后&#xff0c; 为其分配唯一代码的方法。 一个真…

如何做到十五分钟领略PowerBI的DAX精华及框架

有小伙伴问&#xff0c;如何最快速理解整套 DAX 精华体系&#xff0c;例如&#xff1a;15分钟。这虽然是个不可能完成的任务&#xff0c;但在借助脑图PPT的强大能力下&#xff0c;还是可以做到的。如果你从没接触过 DAX&#xff0c;但未来要学习 DAX&#xff0c;以下视频值得看…

springboot配置允许跨域访问

2019独角兽企业重金招聘Python工程师标准>>> 因springboot框架通常用于前后端分离项目&#xff0c;因此需配置后台允许跨域访问&#xff08;具体看注释&#xff09;&#xff0c;配置类如下&#xff0c;将该类加入工程中即可。 import org.springframework.context.a…

机器视觉传感器选型,交互作用决定取舍

目前&#xff0c;如何选择机器视觉传感器在当代的应用可谓是越来越广泛&#xff0c;如何选择机器视觉传感器是值得我们好好学习的&#xff0c;现在我们就深入了解如何选择机器视觉传感器。 相机是机器视觉系统的眼睛&#xff0c;而相机的心脏是图像传感器。传感器的选择取决于准…

使用qrcode类制作二维码

<?phprequire_once ./phpqrcode/phpqrcode.php;/** 地址:http://phpqrcode.sourceforge.net/ 下载qrcode类* param string $url 要生成的链接* param bool $local 是否生成本地文件 * param string $logo 中间图片地址 */ echo qrcode(https://www.cnblogs.co…

《Hadoop大明白》【1】Hadoop的核心组件

为什么80%的码农都做不了架构师&#xff1f;>>> 本书适用于想对大数据平台Hadoop有深入了解的程序员朋友&#xff0c;会帮助你以后在应用开发方面趟平一些坑。 1&#xff0c;Hadoop 是一个系列大数据组件构成的应用平台&#xff0c;可由多个廉价机器搭建集群&#…

.NET7是如何优化Guid.Equals性能的?

简介在之前的文章中&#xff0c;我们多次提到 Vector - SIMD 技术&#xff0c;也答应大家在后面分享更多.NET7 中优化的例子&#xff0c;今天就带来一个使用 SIMD 优化Guid.Equals()方法性能的例子。为什么 Guid 能使用 SIMD 优化&#xff1f;首先就需要介绍一些背景知识&#…