在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
关于.net core高性能编程中的Span<T>和Memory<T>网上资料很多,这里就不说了。今天一直在看ReadOnlySequenceSegment<T>和SequenceReader<T>,看得脑壳痛,本篇着重说说对ReadOnlySequenceSegment<T>的理解。 如果对Span<T>和Memory<T>不了解,可以暂时理解为byte[],最好先去搜下相关资料。缓冲区相关知识可以参考官方文档:https://docs.microsoft.com/zh-cn/dotnet/standard/io/buffers 内存片段ReadOnlySequenceSegment<T>假设你已经了解了Memory<T>,它表示一段连续的内存,有时候我们读取一条数据,它可能并不是存在连续的内存中。 这个我理解得不是很准确,但总体来说就是我们一个完整的数据分成了多个内存片段,每个内存片段用Memory<byte>(你也可以暂时理解为byte[])表示,那么可以以链表的形式,从逻辑上来表示这段完整的数据。比如Memory1上有个next属性指向Memory2,同理Memory2上的next属性指向Memory3,这样的链表就能表示这段完整的数据了。 ReadOnlySequenceSegment<T>就是这样一个链表,3个核心属性定义如下: 1 public ReadOnlyMemory<T> Memory { get; protected set; } 2 public ReadOnlySequenceSegment<T>? Next { get; protected set; } 3 public long RunningIndex { get; protected set; }
这玩意是个抽象类,不过暂时可以不关心,因为我们通常开发时都可以从某个方法的参数获得ReadOnlySequenceSegment<T>(下面马上会说),而它里面就保存着这个链表的收尾两个节点。 这里重点记住:
内存片段容器ReadOnlySequence<T>上面说的这个内存片段链表其实已经可以从逻辑上表示一段完整的数据了,但是ReadOnlySequenceSegment<T>只是这个链表中的一个节点,它能提供的属性、方法等api只能针对自己这个节点,所以需要一个容器来容纳整个链表,以提供对此连续内存片段操作的api 这里说的容器不是很准确,因为ReadOnlySequence只是存储了整个链表的首位节点,但是由于是链表,其实只要知道首节点,就可以通过Next递归获得整个链表的所有节点,因此我这里把它称为容器 下面引用官方文档的一张图
绿色框中有3段蓝色块,我们可以理解为是链表中的一个节点(ReadOnlySequenceSegment),由于这个节点内部重要的就是保存着具体的数据Memory<T>,所以我们可以简单的看成是3个Memory<T>,这里便于理解,也可以看成是3个byte[]。 注:上面简写的16进制,A=0x0A 连续内存片段中的索引SequencePosition只要知道一个数据在哪个片段中,并且知道它在这个片段中的哪个位置,就能表示一个具体的索引了。 但特别注意这个索引是针对原始链表来说的,也就是上面绿色快的部分,比如图片中的“4”在第1段的索引3的位置;“A”,在第2段的索引2处。这种情况没有办法用单个数字来表示索引,因此单独定义了SequencePosition来表示索引。 ReadOnlySequence的api
主要api就这几个。 SequenceReader<T>.net core 3.x提供了SequenceReader来帮我们更容易的读取ReadOnlySequence的数据。我们只要理解一点就能很容易的理解此对象。先看看下图 这里我取名叫“已读索引”,就是表示已经读取过了。SequenceReader.Advance(2)就是将这个索引往后移2位,SequenceReader.Rewind(1)则表示将这个索引前移1位。 以图中为例,若此时调用TryRead方法,则将获取第3个位的数据,并且已读索引向后移1位 理解这个再看官方文档就简单了,举几个例子
其它的就不说了。 收~ |
请发表评论