MemoryOwner<>MemoryOwner<>解决的问题 1.通过ArrayPool的Api MemoryPool 2.IMemoryPool只有Memory属性,我们需要通过Memory再去获取span,但是MemoryOwner<>本身就有span属性供我们调用 3.ArrayPool返回我们租用的缓冲空间的时候默认不会清空,除非设置clearArray,MemoryOwner<>在Allocate的时候就可以设置AllocationMode从而决定在返还缓冲区的时候是否清空其中数据。但是清空数据将会带来小小的性能消耗,就是我们需要给每一位填上默认值,即填充0。 4.MemoryOwner<>最大的优点,就是会重复使用缓冲池中的某个相同的数组,从而最大程度的避免分配。 如下是我们使用原始数组来存储从文件读取到的数据:
如果我们读取的是一个大文件,则会在内存中分配一个大内存空间,这会在使用完之后给GC很大的压力。 我们使用ArrayPool对代码做一个优化,目的在于从缓冲池中租用一段空间,以避免空间的分配。
上述代码有一个很明显的问题,就是最终我们对数组做了切片,所以还是将旧的缓冲区的数据拷贝到了一个新的数组,并且还存在了分配空间的行为。问题的根源就是ArrayPool租用到的大小实际会大于我们的实际请求。并且我们返回了数组,那么我们还需要再去跟踪这个数组的使用的生命周期,并且需要再合适的时机去调用ArrayPool<>.Shared.Return(buffer)返还到缓冲池中。 为了解决上述问题,我们再使用MemoryOwner<>去重构代码
MemoryOwner<>.Allocate(size)返回的IMemoryOwner<> 实例将负责释放基础缓冲区并且MemoryOwner中的所有属性遵循我们请求的实际大小,从而无需再做切片处理,比如Span属性。 SpanOwner<>SpanOwner<>是从共享内存池租用再堆栈中的缓冲区的类型,功能和API与MemoryOwner<>类似。和MemoryOwner<>的区别就是它在堆栈上以及它没有实现IMemoryOwner<>这个接口所以没有Memory<>属性。代码示例: 总结
本文参考文档:https://learn.microsoft.com/zh-cn/dotnet/communitytoolkit/high-performance/memoryowner 如有问题,多谢指教! |
Powered by www.firstproduction.net 第一产经网
备案号:豫ICP备2022016495号-9© 2013-2017 联系我们:939 674 669@qq.com