如何在.NET中创建值类型集合
本文关键字:类型 集合 创建 NET | 更新日期: 2023-09-27 18:21:35
我的应用程序的基本构建块类型分解为一个类型(类或结构),该类型包含一些标准值类型(int、bool等)和标准值类型的一些数组类型,其中集合中会有少量(但未知)元素。
鉴于我有许多以上构建块的实例,我想通过使用数组/集合作为值类型而不是标准引用类型来限制基本类型的内存使用。问题的一部分是,我的标准用法是让数组中包含零个、一个或两个元素,并且在这种情况下,数组引用类型的开销太大了。
我已经根据经验观察到,研究已经证实,数组包装器本身在每个实例中都会引入不必要的(在这种情况下,我认为)开销。
如何使集合成为.NET中的值类型/结构?
旁注:有趣的是,苹果的Swift语言默认将数组作为值类型。
预移情评论
我完全知道以上是使用.NET框架的一种非标准方式,也是非常糟糕的做法等等…所以没有必要对此发表评论。我真的只是想知道如何实现我的要求。
文档中引用的fixed
关键字似乎就是您想要的。它对类型的约束与结构的约束相同,但它确实需要unsafe
。
internal unsafe struct MyBuffer
{
public fixed char fixedBuffer[128];
}
如果您还想在结构中有一个固定的数组,那就更复杂了。fixed
只支持基值类型,因此您必须手动分配内存。
DirectBuffer和BufferPool的想法可以混合使用。
如果使用缓冲池,那么修复内存中的缓冲区并不是一个大问题,因为缓冲区实际上是长寿命的,并且不会像修复没有池的每个新byte[]
那样影响GC压缩。
DirectBuffer使用轻量级模式,并且添加的开销非常小。您可以直接使用指针来读取/写入任何blitable结构。据我所知,除了SBE,Flatbuffers和Cup'n Proto也使用这种方法。在链接的实现中,您应该更改委托,以便它向池返回一个丢弃的byte[]
。
如果您需要与本机代码进行互操作或通过网络发送数据,这种解决方案的最大优势是零拷贝。此外,您可以分配一个缓冲区,并以类似ArraySegment的方式处理偏移量/长度。
更新:
我重读了这个问题,意识到它是专门关于集合作为值类型的。然而,主要的原理似乎是内存压力,所以这个答案可能是内存的替代解决方案,即使DirectBuffer是一个类。