.net core中的高效动态内存管理方案

.net core在新增的System.Buffers中引入了一大堆高效内存管理的类,如span和memory、内存池。本文今天这里介绍一个高效动态内存访问方案。

 

ReadOnlySequenceSegment<T>

在我们读取数据的过程,很多时候会出现如下场景:

  1. 不知道数据实际大小

  2. 一次性申请大量内存开销太大

此时我们往往会使用动态内存的方案,通过链表的方式串联起来,从而形成逻辑意义上的数据流。如下图所示:

640?wx_fmt=png

ReadOnlySequenceSegment<T>就是这样一个表示数据流节点的内存模型,它是一个抽象类,包含如下三个元素:

  • Memory        指向所包含的内存

  • Next        指向下一个节点

  • RunningIndex        标志当前节点在整个流的位置

其中Memory和Next还比较容易理解,典型的链表结构。主要难理解的是RunningIndex,他表示该节点在数据流中的Memory起始索引。

一般的来讲,某节点的RunningIndex为其上一个节点的RunningIndex + Memory.Length。加上RunningIndex估计主要是为了快速索引的。

例如:对于如下3快内存 100byte, 200byte, 300byte组成的链表,其RunningIndex分别是0, 100, 200。

另外,在实际的使用过程中,往往是不停的释放链表头部的节点,并且在尾部添加新节点。 RunningIndex表示的索引一般是逻辑意义上的索引,在释放头节点时,一般不用更新其子节点以及后续节点的RunningIndex。 

ReadOnlySequence<T>

ReadOnlySequenceSegment<T>虽然能解决我们的动态内存的申请和释放问题,但它往往并不好用,因为很容易出现一段连续的数据被分割在多个节点的情况,在这段不连续的数据里进行查询是非常不便的。

为了解决这个问题,.net core中推出了一个视图类ReadOnlySequence<T>

640?wx_fmt=png

ReadOnlySequence<T>由两个属性标记:

  • Start: 起始SequenceSegment以及起始索引

  • End: 结尾SequenceSegment以及结尾索引

可以通过foreach遍历各节点的Memory

  var seq = new ReadOnlySequence<byte>();
  foreach (ReadOnlyMemory<byte> memory in seq)
  {
  }

ReadOnlySequence的主要优势在于,它可以看成一段逻辑意义上的连续内存,常用的函数有:

  • Slice: 对视图数据切片

  • PositionOf: 查询元素的缩影

  • ToArray: 转换成数组

其中的ToArray涉及到大量的数据拷贝,需要谨慎使用。

另外.net core 3.0中还内置了一个SequenceReader,用起来是十分方便的:

640?wx_fmt=png

如何使用

用过System.IO.Pipelines的朋友就知道,ReadOnlySequence在该库中是非常好用的。但如果我们想常见一个ReadOnlySequence,发现并不是那么容易,因为:

  1. ReadOnlySequence依赖于ReadOnlySequenceSegment

  2. ReadOnlySequenceSegment是抽象类,需要自己继承

也就是说我们需要自己实现ReadOnlySequenceSegment<T>,然后再将其封装到ReadOnlySequence中,目前.net core中并没有内置实现可能是因为在高效内存管理的方案中并没有什么通用的解决方案吧。

如果我们要自己实现ReadOnlySequence,一般需要如下几个步骤:

  1. 继承ReadOnlySequenceSegment类,实现自己的SequenceSegment

  2. 在申请内存过程中,创建SequenceSegment,并将其挂成链表

  3. 使用数据时,在该链表中创建ReadOnlySequence

  4. 当SequenceSegment节点的内存使用完成的时候,从链表中接触该节点,并释放内存。

简单来说就是如下几种操作:

  • 数据读取: 创建SequenceSegment

  • 数据使用: 在SequenceSegment链表上创建ReadOnlySequence

  • 使用完成: 释放SequenceSegment

如果要更进一步优化,在SequenceSegment中的内存申请和释放可以使用内存池。

原文地址:https://www.cnblogs.com/TianFang/p/10084049.html

.NET社区新闻,深度好文,欢迎访问公众号文章汇总 http://www.csharpkit.com
640?wx_fmt=jpeg

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

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

相关文章

C. Sum of Log(数位dp)

C. Sum of Log Code1 暴力记的状态 TLE #include<bits/stdc.h> using namespace std; using lllong long; template <class Tint> T rd() {T res0;T fg1;char chgetchar();while(!isdigit(ch)) {if(ch-) fg-1;chgetchar();}while( isdigit(ch)) res(res<<…

APIO游记(5.19-5.23)

概要 本来以为钱基本是白花了 但惊喜的发现其实没有 APIO之后做了几道题&#xff0c;感觉对题目的分析能力增强了 大概虽然不会任何前置算法&#xff0c;但其中的思路多多少少还是吸收到一些 还有一枚Cu诶 针不戳 课程 5.19决策单调性与四边形不等式 第一天 见识到了天高地…

.net core 上 K8S(三)Yaml文件运行.netcore程序

正文上一章我们通过kubectl run简单运行了一个.netcore网站&#xff0c;但实际的开发中&#xff0c;我们都是通过yaml来实现的。1.编写yaml文件关于yaml文件的格式在此就不多描述了&#xff0c;不熟悉的可以去网上搜一下示例。2.运行yamlkubectl create -f netcore.yaml 我们可…

51nod1676-无向图同构【乱搞】

正题 题目连接:http://www.51nod.com/Challenge/Problem.html#problemId1676 题目大意 给出两张nnn个点mmm条边的无向图&#xff0c;求这两张图是否同构。 1≤n≤200,1≤m≤4000,1≤T≤201\leq n\leq 200,1\leq m\leq 4000,1\leq T\leq 201≤n≤200,1≤m≤4000,1≤T≤20 解题…

Jozky模板

文章目录字符串处理后缀数组manacherhashKMP最大最小表达法数论约瑟夫环欧拉函数莫比乌斯反演逆序对归并排序求逆序对素数线性筛欧几里得与扩展欧几里得欧几里得算法&#xff1a;扩展欧几里得算法&#xff1a;逆元扩展欧几里得费马小定理欧拉定理递推求逆元__int128高精度运算唯…

Visual Studio 2017 15.9 版本发布:推出全新的导入 / 导出配置功能

Microsoft 在开发 Visual Studio 2019 的同时&#xff0c;还在继续支持 VS2017 的用户。公司已经发布了 9 次更新&#xff0c;这展示了 Microsoft 在常规更新发布之后仍然会坚守继续支持 Visual Studio 的承诺。我们已经介绍过 15.9 版本中的一些新增内容&#xff0c;但是在最终…

P4780-Phi的反函数【dfs】

正题 题目链接:https://www.luogu.com.cn/problem/P4780 题目大意 给出nnn&#xff0c;求一个最小的xxx满足φ(x)n\varphi(x)nφ(x)n。 若不存在或者大于2312^{31}231则输出−1-1−1。 1≤n≤2311\leq n\leq 2^{31}1≤n≤231 解题思路 考虑用φ\varphiφ比较常用的公式&…

染色(树链剖分 洛谷-P2486)

文章目录题目描述解析代码thanks for reading&#xff01;传送门首先&#xff0c;对hash学姐对本题拔刀相助的debug行为表示衷心的感谢 题目描述 解析 用线段树维护颜色序列个数、最左颜色与最右颜色 合并时如果左儿子的最右颜色等于右儿子的最左颜色&#xff0c;就把加和-1 在…

第 45 届国际大学生程序设计竞赛(ICPC)亚洲区域赛(昆明) AC(带悔贪心)

下面两个题都是选择iii有个价值如果选择iii则不能选择i−1,i1i-1,i1i−1,i1&#xff0c;让价值最大或最小 P1792 [国家集训队]种树 野心qwq 的博客 #include<bits/stdc.h>using namespace std;const int N200010; int n,m; int a[N]; int fr[N],to[N]; priority_queue…

C# 8中的范围类型(Range Type)

C# 8.0中加入了一个新的范围类型(Range Type)。这里我们首先展示一些代码&#xff0c;并一步一步为代码添加一些不同的东西, 为大家展示一下范围类型的功能和用法。我们最原始的代码如下&#xff1a;这里我们显示的定义了我们查询数组的索引1-3, 并输出他们的值。毫无疑问&…

bzoj#4423-[AMPPZ2013]Bytehattan【并查集】

正题 题目链接:https://darkbzoj.tk/problem/4423 题目大意 给出一个n∗nn*nn∗n的网格图&#xff0c;然后四联通的点之间连接。每次删掉一条边求这条边的两个点是否连通。强制在线。 1≤n≤1500,1≤m≤2n(n−1)1\leq n\leq 1500,1\leq m\leq 2n(n-1)1≤n≤1500,1≤m≤2n(n−…

选数游戏(ybtoj-二叉堆)

文章目录题目描述解析代码thanks for reading&#xff01;题目描述 解析 一道很考验代码能力与思维的题 &#xff08;我不是在为自己的菜找理由&#xff09; 首先由于可以每一列都有类似于环的性质 所以我们可以忽略点的出入的纵坐标的位置&#xff0c;只考虑每列选几个 首先&…

CF741C Arpa’s overnight party and Mehrdad’s si

题目描述&#xff1a; 有n对情侣&#xff08;2n个人&#xff09;围成一圈坐在桌子边上&#xff0c;每个人占据一个位子&#xff0c;要求情侣不能吃同一 种食物&#xff0c;并且桌子上相邻的三个人的食物必须有两个人是不同的&#xff0c;只有两种食物&#xff08;1或者是2&…

开源库支付库Magicodes.Pay发布

Magicodes.Pay&#xff0c;是心莱科技团队提供的统一支付库&#xff0c;相关库均使用.NET标准库编写&#xff0c;支持.NET Framework以及.NET Core。目前支持以下支付方式和功能&#xff1a;支付宝APP支付支付宝Wap支付支付宝国际支付 支持分账微信小程序支付微信APP支付统一支…

火车载客(ybtoj-二叉堆)

文章目录题目描述解析我的思路代码题解思路题目描述 解析 我的思路 其实就是线段覆盖的一个变体 贪心的想&#xff1a; 把游客按右端点升序排序 后面的证明就和线段覆盖一样了 如果有两个游客冲突 我们应该选右端点靠右的 因为这样对以后继续在右边出现的游客来说肯定不会更差…

CF835E-The penguin‘s game【交互】

正题 题目链接:https://www.luogu.com.cn/problem/CF835E 题目大意 长度为nnn的序列中有两个yyy其他都是xxx&#xff0c;给出n,x,yn,x,yn,x,y。你每次可以询问一个下标集合的数字异或和&#xff0c;要求在191919次以内找到这两个yyy的位置。 1≤n≤1000,1≤x,y≤109,x≠y1\le…

2021 CCPC E. 被遗忘的计划(循环卷积+快速幂)

E. 被遗忘的计划 别人的简洁写法 #include<bits/stdc.h>using namespace std; using lllong long; const ll INF0x3f3f3f3f3f3f3f3fll; const ll mod1e97; using vlvector<ll>; vl operator *(vl a,vl b) {vl v(a.size(),-INF);for(int i0;i<a.size();i)for(i…

NetCore基于EasyNetQ的高级API使用RabbitMq

一、消息队列消息队列作为分布式系统中的重要组件&#xff0c;常用的有MSMQ&#xff0c;RabbitMq&#xff0c;Kafa&#xff0c;ActiveMQ&#xff0c;RocketMQ。至于各种消息队列的优缺点比较&#xff0c;在这里就不做扩展了&#xff0c;网上资源很多。更多内容可参考 消息队列及…

bzoj#4722-由乃【倍增,抽屉原理,bitset】

正题 题目链接:https://darkbzoj.tk/problem/4722 题目大意 给出一个长度为nnn的序列值域为[0,v)[0,v)[0,v)&#xff0c;要求支持操作 询问一个区间能否找到两个没有交的非空下标集合使得这些位置的和加上集合的大小相等。区间立方然后取模vvv。 1≤n≤105,1≤v≤10001\leq …