Json序列化与反序列化导致多线程运行速度和单线程运行速度一致问题
紧跟上篇文章 十个进程开启十个bash后一致写入命令执行完毕之后产生了很多很多的文件,博主需要对这些文件同意处理,也就是说对几十万个文件进行处理,想了又想,单线程处理那么多数据肯定不行,于是乎想到了使用多线程,紧接着就引发了一系列问题,其中做大的问题就是json序列化,导致了多条线程运行和单线程运行时间一致问题。
我们正常去读取json文件转成一般是通过实体类去使用JsonConvert.DeserializeObject方法进行接收的,然后再通过实体类去进行一系列的操作,目前遇到的问题就是读取上万的json文件进行反序列化与序列化进行操作,如果一条一条的去操作的话速度可谓是非常非常慢,然后经过大佬的推荐和自己了解决定使用微软专门推出的一个操作json的类。
这个类说的也非常清楚,提供高性能、低分配和标准兼容的功能,以处理 JavaScript 对象表示法 (JSON),其中包括将对象序列化为 JSON 文本以及将 JSON 文本反序列化为对象(内置 UTF-8 支持)。 它还提供类型以用于读取和写入编码为 UTF-8 的 JSON 文本,以及用于创建内存中文档对象模型 (DOM) 以在数据的结构化视图中随机访问 JSON 元素。
虽然这个类库专门针对于性能来优化的,但是使用起来往往非常的困难,没有我们大众所使用的JsonConvert.DeserializeObject方便,但是如像我一样对待性能有极致的要求的话,可以使用这个类库,用法也非常简单,下面我给出例子
引入命名空间:
System.Text.Json
那么具体如何使用呢?我这里给出具体的使用方法以及详细的例子。
JsonDocument document1 = null; StreamReader f2 = new StreamReader(filePath, Encoding.UTF8);
String line;
while ((line = f2.ReadLine()) != null)
{
document1 = JsonDocument.Parse(line);
}
f2.Close();
f2.Dispose();
这里我们去读取filepath,filepath是json文件路径。我们使用 JsonDocument.Parse对json文件进行操作。这个方法表示单个 JSON 字节值的 UTF-8 编码文本形式的序列分析为 JsonDocument。
把json文件序列分析为JsonDocument类型了下面就是对这个类型进行操作,为什么现在好多人不喜欢使用这种方法,大概率是因为取值比较难
对于JsonDocument如何取出我们想要的值或者节点呢?看下面的例子:
{
"ClassName": "Science",
"Teacher\u0027s Name": "Jane",
"Semester": "2019-01-01",
"Students": [
{
"Name": "John",
"Grade": 94.3
},
{
"Name": "James",
"Grade": 81.0
},
{
"Name": "Julia",
"Grade": 91.9
},
{
"Name": "Jessica",
"Grade": 72.4
},
{
"Name": "Johnathan"
}
],
"Final": true
}
上述是一个json文件内的数据,我们解析JsonDocument如何解析出Class Name节点值呢?
可以使用如下操作
//定义变量去接收
var className = "0";
//判断我们解析出来的JsonDocument是否为空
if (document1 != null)
{
JsonElement root = document1.RootElement;
className = root.TryGetProperty("ClassName", out var temp) ? temp.GetInt32().ToString() : "0";
}
首先使用 JsonDocument.RootElement属性 获取此 JSON 文档的根元素。
对于根元素进行解析,JsonElemet.TryGetProperty() 查找当前对象中名为 ClassName 的属性,返回一个指示此类属性是否存在的值。 如果此属性存在,会将其值分配给 value 参数。现在value参数对应temp,解析时还应注意属性值类型,如果为string类型则使用GetString(),去进行转换,int类型可以使用GetInt32(),进行转换,具体其他类型可以查看微软官方给出的类型。
使用TryGetProperty()方法有什么好处呢?
可以去判断json文件内有没有当前的属性,如果有的话,去返回属性值,无,则返回null。
现在我们取单独属性已经会了,那么如何取数组呢?如何取数组对象呢?
例子:
double sum = 0;
int count = 0; using (JsonDocument document = JsonDocument.Parse(jsonString))
{
JsonElement root = document.RootElement;
JsonElement studentsElement = root.GetProperty("Students");
count = studentsElement.GetArrayLength(); foreach (JsonElement student in studentsElement.EnumerateArray())
{
if (student.TryGetProperty("Grade", out JsonElement gradeElement))
{
sum += gradeElement.GetDouble();
}
else
{
sum += 70;
}
}
} double average = sum / count;
Console.WriteLine($"Average grade : {average}");
上面这个例子是微软官方给出的例子,但是使用与我们已经知道json文件格式的情况。
使用之前我们可以使用TryGetProperty方法先判断json属性是否存在,存在的话去定义一个value值进行接收,先判断是否为存在,存在则把value值进行遍历,然后再去判断这个数组内的属性是否存在,存在的话返回属性值,以此类推便可以拿到所有的json文件中的属性值啦!
性能提升:说了这么多到底这种方法能够提升多少速度呢,经过博主测试JsonConvert.DeserializeObject方法在线程或者进程内使用的话开启多个和单个线程(进程)速度相差基本不大,就好比我开了十个线程,去读取十万个文件,结果和单个线程去读取十万个文件相差几秒??是不是非常离谱。
换用这种高性能处理json文件的类库之后,开启十个线程去操作文件速度直接减少了三分之二!!!!!!
Json序列化与反序列化导致多线程运行速度和单线程运行速度一致问题的更多相关文章
- Newtonsoft.Json 序列化和反序列化 时间格式
From : http://www.cnblogs.com/litian/p/3870975.html 1.JSON序列化 string JsonStr= JsonConvert.SerializeO ...
- Newtonsoft.Json 序列化和反序列化 时间格式 [转]
1.JSON序列化 string JsonStr= JsonConvert.SerializeObject(Entity); eg: A a=new A(); a.Name="Elain ...
- [转]Newtonsoft.Json 序列化和反序列化 时间格式
本文转自:http://www.cnblogs.com/litian/p/3870975.html 1.JSON序列化 string JsonStr= JsonConvert.SerializeObj ...
- Newtonsoft.Json 序列化和反序列化 以及时间格式
1.JSON序列化 string JsonStr= JsonConvert.SerializeObject(Entity); eg: A a=new A(); a.Name="Elain ...
- WPF中的常用布局 栈的实现 一个关于素数的神奇性质 C# defualt关键字默认值用法 接口通俗理解 C# Json序列化和反序列化 ASP.NET CORE系列【五】webapi整理以及RESTful风格化
WPF中的常用布局 一 写在开头1.1 写在开头微软是一家伟大的公司.评价一门技术的好坏得看具体的需求,没有哪门技术是面面俱到地好,应该抛弃对微软和微软的技术的偏见. 1.2 本文内容本文主要内容 ...
- 在net中json序列化与反序列化 面向对象六大原则 (第一篇) 一步一步带你了解linq to Object 10分钟浅谈泛型协变与逆变
在net中json序列化与反序列化 准备好饮料,我们一起来玩玩JSON,什么是Json:一种数据表示形式,JSON:JavaScript Object Notation对象表示法 Json语法规则 ...
- DotNet的JSON序列化与反序列化
JSON(JavaScript Object Notation)JavaScript对象表示法,它是一种基于文本,独立于语言的轻量级数据交换格式.在现在的通信中,较多的采用JSON数据格式,JSON有 ...
- C#中JSON序列化和反序列化
有一段时间没有到博客园写技术博客了,不过每天逛逛博客园中大牛的博客还是有的,学无止境…… 最近在写些调用他人接口的程序,用到了大量的JSON.XML序列化和反序列化,今天就来总结下json的序列化和反 ...
- Net中JSON序列化和反序列化处理(日期时间特殊处理)
0 缘由 笔者最近在web api端使用Json.Net进行序列化处理,而在调用端使用DataContractSerializer进行反序列化,遇到日期时间处理反序列化不成功[备注:笔者使用Net ...
随机推荐
- CAS和CAP代表的作用
CAS(自旋锁):https://www.jianshu.com/p/ab2c8fce878b CAP原则:https://baike.baidu.com/item/CAP原则/5712863?fr= ...
- JS的箭头函数this作用域
name="小刚"; let student={ name:"小明", printLog:function(){ // 这里绑定了顶层作用域,可以使用变量与方法 ...
- 不同版本的 Spring Framework 有哪些主要功能?
Version Feature Spring 2.5 发布于 2007 年.这是第一个支持注解的版本. Spring 3.0 发布于 2009 年.它完全利用了 Java5 中的改进,并为 JEE6 ...
- 一个注解@Recover搞定丑陋的循环重试代码
使用背景 在实际项目中其中一部分逻辑可能会因为调用了外部服务或者等待锁等情况下出现不可预料的异常,在这个时候我们可能需要对调用这部分逻辑进行重试,代码里面主要就是使用for循环写一大坨重试的逻辑,各种 ...
- Spring官宣网传大漏洞,并提供解决方案
Spring沦陷了!这样的标题这几天是不是看腻了?然而,仔细看看都是拿着之前的几个毫不相干的CVE来大吹特吹.所以,昨天发了一篇关于最近网传的Spring大漏洞的文章,聊了聊这些让人迷惑的营销文.以及 ...
- mian中的argv调用时为什么不是*argv
c++main函数char * argv[]是个指针数组,元素是指针,为何argv[1]得到不是地址? 照我的理解char *argv[]保存的应该是一组指针,即地址,每个地址中保存的是char类型变 ...
- 在页面未加载完之前显示loading动画
在页面未加载完之前显示loading动画 这里有很多比这篇博客还优秀的loading动画源码 我还参考这篇博客 loading动画代码demo 我的demo预览 <!DOCTYPE html&g ...
- 探讨:微信小程序应该如何设计
微信小程序公测后,开发者非常热情,都有很高的期待,都想抓住这一波红利.但是热情背后需要冷静,我们需要搞清楚两个问题: 微信想要我们做什么?微信小程序可以做什么? 微信想要我们做什么? 首先来弄清楚微信 ...
- Android实现蓝牙远程连接遇到的问题
主要问到的问题:1.uuid获取不到,一直为空,后来发现android4.2之前使用uuid这种方法,目前尽量不使用uuid方式 2.socket.connect()出错,报read failed, ...
- CCF201409-3 字符串匹配
问题描述 给出一个字符串和多行文字,在这些文字中找到字符串出现的那些行.你的程序还需支持大小写敏感选项:当选项打开时,表示同一个字母的大写和小写看作不同的字符:当选项关闭时,表示同一个字母的大写和小写 ...