dotnet 6 在 System.Text.Json 使用 source generation 源代码生成提升 JSON 序列化性能
这是一个在 dotnet 6 早就引入的功能,此功能的使用方法能简单,提升的效果也很棒。使用的时候需要将 Json 序列化工具类换成 dotnet 运行时自带的 System.Text.Json 进行序列化,再加上约 5 行的辅助代码,即可完成对接
官方文档: 如何在 System.Text.Json 中使用源生成 Microsoft Learn
先假定有名为 WeatherForecast 的类型,定义如下
public class WeatherForecast
{
public DateTime Date { get; set; }
public int TemperatureCelsius { get; set; }
public string? Summary { get; set; }
}
此类型将要进行 Json 的序列化
为了能让此类型接入 source generation 源代码生成,生成 Json 序列化和反序列化的自动生成代码逻辑,需要再加上以下的约 5 行的辅助代码
[JsonSerializableAttribute(typeof(WeatherForecast))]
internal partial class MyJsonContext : JsonSerializerContext
{
}
以上代码是随意新建一个类型,类型的名称没有约束,让此类型继承 JsonSerializerContext 类型,且标记 JsonSerializableAttribute 特性,在此特性上面加上需要对接的原始数据类型,如 WeatherForecast 类
标记了 JsonSerializableAttribute 特性之后,将可以在 Visual Studio 的解决方案资源管理器里面的项目的依赖项->分析器->System.Text.Json.SourceGeneration->System.Text.Json.SourceGeneration.JsonSourceGeneration 里面,展开看到 xx.g.cs 文件
这些 xx.g.cs 文件就是生成的文件,想不开可以点进去看看,核心逻辑就是写了如何从原始数据类型进行转换获取 Json 的属性和值对应关系,也就是对每个属性构建出 JsonPropertyInfoValues 类型
比如说对上面的 WeatherForecast 的 Date 属性进行生成,生成的代码大概如下,以下代码最重要的有三个点,分别是如何获取和如何设置,以及属性名
new global::System.Text.Json.Serialization.Metadata.JsonPropertyInfoValues<global::System.DateTime>()
{
IsProperty = true,
IsPublic = true,
IsVirtual = false,
DeclaringType = typeof(global::GemjabemrawWohearcebola.WeatherForecast),
PropertyTypeInfo = jsonContext.DateTime,
Converter = null,
// 告诉 json 框架,如何进行赋值和获取值
Getter = static (obj) => ((global::GemjabemrawWohearcebola.WeatherForecast)obj).Date,
Setter = static (obj, value) => ((global::GemjabemrawWohearcebola.WeatherForecast)obj).Date = value!,
IgnoreCondition = null,
HasJsonInclude = false,
IsExtensionData = false,
NumberHandling = default,
// 告诉 json 框架,这个属性名叫什么
PropertyName = "Date",
JsonPropertyName = null
}
大家都知道,在 JSON 反序列化里面,可以强行分为两步。第一步就是对 JSON 这个格式本身的处理,展开为内存模型。第二步就是从展开的内存模型转换为具体的类型。同理,序列化也是相同的道理
其中第一步对 Json 这个格式本身的处理方面上,这是可以做到非常通用的。但是第二步就会根据具体的业务开发,转换为不同的类型。在此之前,这个转换步骤基本都是采用反射来实现的。而大家都知道,反射的性能是跟不上的。如今有了 Source Generation 源代码生成,就可以使用生成的代码实现此第二步的逻辑,通过生成的代码,从 json 展开的内存模型,对接到具体的类型上,给对应的具体类型的对象的各个属性调用赋值方法,通过生成的代码了解到对象的属性名,获取到匹配的属性的值
这就是为什么使用 Source Generation 源代码生成能在 Json 序列化中提升性能的原因
写完了 MyJsonContext 类型之后,再来看看如何对接 JSON 反序列化和序列化逻辑
只需要调用 JsonSerializer 的 对应的反序列化和序列化方法,传入 MyJsonContext 对应的参数即可,传入参数的作用是让 System.Text.Json 底层可以了解到如何应用上源代码生成的代码
假定有以下字符串,准备用来反序列化
string jsonString =
@"{
""Date"": ""2019-09-01T00:00:00"",
""TemperatureCelsius"": 25,
""Summary"": ""Hot""
}
";
逻辑代码可以如此写
WeatherForecast? weatherForecast;
weatherForecast = JsonSerializer.Deserialize<WeatherForecast>(
jsonString, MyJsonContext.Default.WeatherForecast);
Console.WriteLine($"Date={weatherForecast?.Date}");
可以看到,在 Deserialize 方法里面,将 MyJsonContext.Default.WeatherForecast 作为参数传入。如此即可让 System.Text.Json 使用到 MyJsonContext 的生成代码
反过来,在拿到 WeatherForecast 对象之后,可以调用 Serialize 方法进行序列化,同理传入 MyJsonContext.Default.WeatherForecast 用来对接生成代码
jsonString = JsonSerializer.Serialize(
weatherForecast!, MyJsonContext.Default.WeatherForecast);
Console.WriteLine(jsonString);
以上的例子代码都是从官方文档抄的,更多用法还请参阅官方文档
如何在 System.Text.Json 中使用源生成 Microsoft Learn
dotnet 6 在 System.Text.Json 使用 source generation 源代码生成提升 JSON 序列化性能的更多相关文章
- 【json/regex】将简单对象生成的json文进行内部排序后再输出
有这样一个实体类: package com.hy; public class Emp { private int id; private int age; private String name; p ...
- [译]试用新的System.Text.Json API
译注 可能有的小伙伴已经知道了,在.NET Core 3.0中微软加入了对JSON的内置支持. 一直以来.NET开发者们已经习惯使用Json.NET这个强大的库来处理JSON. 那么.NET为什么要增 ...
- C# Serialization performance in System.Runtime.Serialization.Formatters.Binary.BinaryFormatter,Newtonsoft.Json.JsonConvert and System.Text.Json.JsonSerializer.Serialize
In .net core 3.0 using System;using System.Collections.Generic;using System.Collections;using System ...
- .NET Core 3.0 System.Text.Json 和 Newtonsoft.Json 行为不一致问题及解决办法
行为不一致 .NET Core 3.0 新出了个内置的 JSON 库, 全名叫做尼古拉斯 System.Text.Json - 性能更高占用内存更少这都不是事... 对我来说, 很多或大或小的项目能少 ...
- .NET 5的System.Text.Json的JsonDocument类讲解
本文内容来自我写的开源电子书<WoW C#>,现在正在编写中,可以去WOW-Csharp/学习路径总结.md at master · sogeisetsu/WOW-Csharp (gith ...
- 【译】System.Text.Json 的下一步是什么
.NET 5.0 最近发布了,并带来了许多新特性和性能改进.System.Text.Json 也不例外.我们改进了性能和可靠性,并使熟悉 Newtonsoft.Json 的人更容易采用它.在这篇文章中 ...
- 使用System.Text.Json处理Json文档以及部分坑
System.Text.Json处理Json文档需要用到JsonDocument,JsonElement,JsonProperty. JsonDocument就是一个表示Json文档的东西,JsonE ...
- 在.Net Core 3.0中尝试新的System.Text.Json API
.NET Core 3.0提供了一个名为System.Text.Json的全新命名空间,它支持reader/writer,文档对象模型(DOM)和序列化程序.在此博客文章中,我将介绍它如何工作以及如何 ...
- .netcore3.0 System.Text.Json 日期格式化
.netcore3.0 的json格式化不再默认使用Newtonsoft.Json,而是使用自带的System.Text.Json来处理. 理由是System.Text.Json 依赖更少,效率更高. ...
- In .net 4.8,calculate the time cost of serialization in BinaryFormatter,NewtonSoft.json,and System.Text.Json.JsonSerializer.Serialize
using ConsoleApp390.Model; using Newtonsoft.Json; using System; using System.Collections.Generic; us ...
随机推荐
- 恶意软件开发(三)经典DLL注入流程
什么是dll注入? DLL注入允许将外部DLL文件加载到进程中并运行其中的代码.DLL(动态链接库)是一种可重用的代码库,它包含在多个程序中使用的函数.类.变量和其他程序代码.DLL注入技术可以通过将 ...
- 在 .NET 中使用 OPC UA 协议
目录 什么是 OPC UA UaExpert 的使用 下载 UaExpert 首次启动 添加 OPC UA 服务器 连接 OPC UA 服务器 查看 PLC 数据 使用 C# 读写 OPC UA 数据 ...
- CDN 引入 axios 和 qs 及其使用方法
一些小项目,没必要搭建脚手架,直接以CDN的方式引入 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN&quo ...
- Python数据库编程全指南SQLite和MySQL实践
本文分享自华为云社区<Python数据库编程全指南SQLite和MySQL实践>,作者: 柠檬味拥抱. 1. 安装必要的库 首先,我们需要安装Python的数据库驱动程序,以便与SQLit ...
- linux xfce 设置限制亮度滑块的最小亮度,在屏幕里的xfce设置亮度的最小亮度。
参照 https://docs.xfce.org/xfce/xfce4-power-manager/preferences 使用代码 xfconf-query -c xfce4-power-manag ...
- 2021 年 25 大 DevOps 工具(上)
DevOps 正在改变全球软件开发的状态,DevOps 正以某种形式有效地提高提高全球软件公司的上市速度.可销售性.创新和产品质量.2021 年是 DevOps 的重要一年.由于 DevOps 跨越开 ...
- #分类讨论#CF891A Pride
题目 你有一个长度为 \(n\) 的数列 \(a\),你能执行一些操作. 每个操作是这样的:选择两个相邻的数 \(x\) 和 \(y\),把 它们中的一个 换为 \(\gcd(x,y)\). 问你把数 ...
- #并查集,线性筛#nssl 1470 X
分析 显然答案就是\(2^{连通块个数}-2\), 将每个数的质数所在的集合合并, 最后判断连通块个数即可(线性筛少了个等号改了半天QWQ) 代码 #include <cstdio> #i ...
- #根号分治,树上倍增#洛谷 3591 [POI2015]ODW
题目 分析 考虑直接用倍增跳会TLE,设\(f[x][i]\)表示以\(x\)为起点每次跳\(i\)步的点权和, 这可以预处理出来,综合一下两种做法,当\(i>\sqrt{n}\)时直接上倍增, ...
- Maven的build生命周期和常用plugin
目录 简介 lifecycle和Phases Phases和Goals 常用plugin介绍 maven-dependency-plugin maven-jar-plugin 总结 简介 Maven和 ...