在.NET中,是否可以使用非安全代码实现高效的固定大小数组?

10

是否有一种在.NET中实现固定大小数组的良好方法而不需要使用unsafe代码?

我的目标是创建一个值类型,它代表可以嵌入(作为成员包含)到其他类型中的固定大小数组 - 即我希望特别避免将数组作为声明它的类型的单独对象创建。

我意识到.NET的数组实现非常出色并且在CLR/CIL级别受支持 - 并不想争论是否只使用数组...这里的探讨是关于安全、固定大小和价值类型实现是否可能达到几乎同样好的效率。


2
你能帮我理解这提供了什么好处,而普通数组(在类型内声明)不能提供的吗?如果我甚至不知道目标是什么,很难想出替代实现。这是否是为了消除此处概述的数组中所述的一些异议?:http://blogs.msdn.com/b/ericlippert/archive/2008/09/22/arrays-considered-somewhat-harmful.aspx - Robert Harvey
1
@Robert:目标是要能够拥有一个固定大小的值类型数组,该数组可以作为其他类型的私有成员使用。考虑自定义字典或链表实现... 如果每个桶/节点被展开以包含其自己的固定大小数组,则堆分配的数量可以减少。 - Mark
2个回答

5
目标是创建一个固定大小的值类型数组,可以作为其他类型的私有成员使用。考虑自定义字典或链表实现...如果每个桶/节点被展开以包含自己的固定大小数组,则可以减少堆分配次数。
将数组设置为值类型并不一定意味着它将存储在堆栈上。实际上,如果它是嵌入在引用类型中的值类型,它很可能会与引用类型一起存储在堆上,而不是在堆栈上。
因此,将其设置为值类型不会减少堆分配次数。
更多信息请参见此处

是的,这将最终在堆上结束。毫无疑问,他将不断复制这个512字节的结构。 - Hans Passant
2
这个问题的想法是将结构体嵌入到类中,并使结构体与类一起在堆上分配。如果作为私有成员实现并正确使用,则不应该多次复制它。 - Mark
1
它将减少堆分配,因为它现在只为包含类分配一次(而不是为数组再次分配)。 - Eamon Nerbonne

2
经过使用反射器的一些研究,发现以下方法是可接受的(从性能角度考虑),因为C#将整数类型的switch语句编译成CIL switch语句,并实现为跳转列表...也就是说,getter执行大约需要11个CIL指令,这是可以接受的。
 public struct EmbeddedArray<T>
    {
        private T _element0;
        private T _element1;
        private T _element2;

        public int Length { get { return 3; } }


        public T this[int index]
        {
            get
            {
                switch (index)
                {
                    case 0:
                        return _element0;
                    case 1:
                        return _element1;
                    case 2:
                        return _element2;
                }
                throw new ArgumentOutOfRangeException("index");

            }
        }
    }

请看下面Hans的评论。事实证明,这并不像我所希望的那样具有高性能...一旦CIL编译成本地机器代码,测量的性能远远达不到.NET数组的水平。

6
仅查看IL是无意义的,只有JIT生成的机器代码才相关。而且这段代码应该比数组索引执行得要慢很多。由于跳转表很大,因此它的缓存局部性非常差。而且几乎肯定会出现分支预测错误,这在现代处理器上是非常昂贵的。数组索引没有这些问题。使用实际数据对其进行分析以了解这一点。 - Hans Passant
2
@Hans - 再次向您致以最高的敬意,感谢您的评论。经过一些分析,事实证明您是正确的... IL switch语句有点误导人。此外,将数组分配给使用它的类的成本非常低廉,这是为了获得数组性能提升所付出的代价。Hans,你真棒!我希望您发布一个答案而不是评论 - 这将是被接受的答案。 - Mark
1
你问题中的最后一段排除了讨论正确答案的可能性。 - Hans Passant

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接