.net开发者应掌握的利器CommunityToolkit.HighPerformance——MemoryOwner与SpanOwner
2023/6/1 5:22:48
本文主要是介绍.net开发者应掌握的利器CommunityToolkit.HighPerformance——MemoryOwner与SpanOwner,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
MemoryOwner和SpanOwner都可以理解为是对ArrayPool<>的一个包装,无非一个是在堆栈上,一个是在托管堆上。既然做了包装,那肯定随之而来就是改进和优化。
目录
- MemoryOwner<>
- MemoryOwner<>解决的问题
- SpanOwner<>
- 总结
MemoryOwner<>
MemoryOwner<>解决的问题
1.通过ArrayPool的Api MemoryPool
2.IMemoryPool只有Memory属性,我们需要通过Memory再去获取span,但是MemoryOwner<>本身就有span属性供我们调用
3.ArrayPool返回我们租用的缓冲空间的时候默认不会清空,除非设置clearArray,MemoryOwner<>在Allocate的时候就可以设置AllocationMode从而决定在返还缓冲区的时候是否清空其中数据。
但是清空数据将会带来小小的性能消耗,就是我们需要给每一位填上默认值,即填充0。
4.MemoryOwner<>最大的优点,就是会重复使用缓冲池中的某个相同的数组,从而最大程度的避免分配。
如下是我们使用原始数组来存储从文件读取到的数据:
using Stream stream = File.OpenRead(path); byte[] buffer = new byte[(int)stream.Length]; stream.Read(buffer, 0, buffer.Length); return buffer;
如果我们读取的是一个大文件,则会在内存中分配一个大内存空间,这会在使用完之后给GC很大的压力。
我们使用ArrayPool对代码做一个优化,目的在于从缓冲池中租用一段空间,以避免空间的分配。
using Stream stream = File.OpenRead(path); byte[] buffer = ArrayPool<byte>.Shared.Rent((int)stream.Length); stream.Read(buffer, 0, (int)stream.Length); //切片数组 return buffer[0..((int)stream.Length - 1)];
上述代码有一个很明显的问题,就是最终我们对数组做了切片,所以还是将旧的缓冲区的数据拷贝到了一个新的数组,并且还存在了分配空间的行为。问题的根源就是ArrayPool租用到的大小实际会大于我们的实际请求。
并且我们返回了数组,那么我们还需要再去跟踪这个数组的使用的生命周期,并且需要再合适的时机去调用ArrayPool<>.Shared.Return(buffer)返还到缓冲池中。
为了解决上述问题,我们再使用MemoryOwner<>去重构代码
using Stream stream = File.OpenRead(path); MemoryOwner<byte> buffer = MemoryOwner<byte>.Allocate((int)stream.Length); stream.Read(buffer.Span); return buffer;
MemoryOwner<>.Allocate(size)返回的IMemoryOwner<> 实例将负责释放基础缓冲区
并且MemoryOwner中的所有属性遵循我们请求的实际大小,从而无需再做切片处理,比如Span属性。
SpanOwner<>
SpanOwner<>是从共享内存池租用再堆栈中的缓冲区的类型,功能和API与MemoryOwner<>类似。
和MemoryOwner<>的区别就是它在堆栈上以及它没有实现IMemoryOwner<>这个接口所以没有Memory<>属性。
代码示例:
SpanOwner<int> buffer = SpanOwner<int>.Allocate(length); Span<int> span = buffer.Span;
总结
1.SpanOwner和MemoryOwner常被用作缓冲区,存储临时数据
2.可以使用using对SpanOwner和MemoryOwner进行生命周期的控制,对于MemoryOwner来说,如果不方便控制,GC最后也会将其返还到缓冲池中。
3.SpanOwner和MemoryOwner可以理解为是对ArrayPool的包装。
本文参考文档:https://learn.microsoft.com/zh-cn/dotnet/communitytoolkit/high-performance/memoryowner
如有问题,多谢指教!
这篇关于.net开发者应掌握的利器CommunityToolkit.HighPerformance——MemoryOwner与SpanOwner的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2022-03-01沐雪多租宝商城源码从.NetCore3.1升级到.Net6的步骤
- 2024-12-06使用Microsoft.Extensions.AI在.NET中生成嵌入向量
- 2024-11-18微软研究:RAG系统的四个层次提升理解与回答能力
- 2024-11-15C#中怎么从PEM格式的证书中提取公钥?-icode9专业技术文章分享
- 2024-11-14云架构设计——如何用diagrams.net绘制专业的AWS架构图?
- 2024-05-08首个适配Visual Studio平台的国产智能编程助手CodeGeeX正式上线!C#程序员必备效率神器!
- 2024-03-30C#设计模式之十六迭代器模式(Iterator Pattern)【行为型】
- 2024-03-29c# datetime tryparse
- 2024-02-21list find index c#
- 2024-01-24convert toint32 c#