C# 在与类相同的对象中分配数组

C# 在与类相同的对象中分配数组,c#,optimization,C#,Optimization,我在一个类中有一个数组: class MatchNode { public short X; public short Y; public NodeVal[] ControlPoints; private MatchNode() { ControlPoints = new NodeVal[4]; } } NodeVal是: struct NodeVal { public readonly short X; pub

我在一个类中有一个数组:

class MatchNode
{
    public short X;
    public short Y;
    public NodeVal[] ControlPoints;

    private MatchNode()
    {
        ControlPoints = new NodeVal[4];
    }
}
NodeVal
是:

struct NodeVal
{
    public readonly short X;
    public readonly short Y;

    public NodeVal(short x, short y)
    {
        X = x;
        Y = y;
    }
}
现在,如果我们想将性能提升到一个新的水平,并且避免为数组使用单独的对象,该怎么办。实际上,它不必有数组。唯一的限制是客户端代码应该能够通过如下索引访问
NodeVal

matchNode.ControlPoints[i]

当然,解决方案应该更快或与阵列访问一样快,因为它应该是一种优化

编辑:正如Ryan建议的那样,我似乎应该更多地解释动机:

MatchNode
类在项目中大量使用。项目中使用了数以百万计的缓存,每一个都被访问了数百次,因此尽可能紧凑和简洁可以减少缓存未命中和总体性能

我们考虑一个64位的机器。在当前的实现中,类数组需要8个字节作为控制点引用,数组对象的大小将至少为对象开销的16字节(对于方法表和同步块)和实际字节的16字节。因此,除了16字节的实际数据外,我们还有至少24个开销字节

这些对象用于项目的瓶颈,所以我们是否可以对它们进行更多优化很重要

当然,我们可以有一个超级大的
NodeVal
数组,只需在
MatchNode
中保存一个索引即可定位实际数据,但它会再次更改使用
MatchNode
的每个客户端代码,更不用说是一个肮脏的非面向对象解决方案了

有一个凌乱的
MatchNode
,它使用各种讨厌的技巧,如不安全或静态缓存代码,这是可以的。将这些优化泄露给客户端代码是不合适的。

您正在寻找:

现在,您可以简单地使用:

var m = new MatchNode(10);
m[0] = new NodeVal();

但是,我怀疑这会影响性能(至少在速度方面),并且你应该使用一个分析工具(DoTrink)来考虑实际问题。此外,这种方法还将创建一个私有备份字段,该字段将产生相同的内存占用。

您能解释一下您已有的内存有什么问题吗?你具体关心什么?虽然当有更好的集合可用时(如
列表
),阵列并不理想,但是什么让您认为您的代码存在性能问题?您真的关心这种微观优化(我甚至怀疑它是否会对性能产生影响)?您应该明确注意分析工具(例如DotTrace)发现的实际性能问题?不过,这可能比仅仅公开一个阵列要慢!您可以使用索引属性公开类中的值,但您仍然需要一个底层数据结构,它是数组、列表还是链表将取决于您的具体要求。您的注释回答使本文更加清晰。。。而且很有趣。您应该考虑编辑帖子并添加这些信息。这个版本在类中也有一个数组。整个要点是删除数组以及与之相关的内存和解引用开销
class MatchNode
{
    public short X;
    public short Y;
    private NodeVal[] myField;
    public NodeVal this[int i] { get { return myField[i]; } set { myField[i] = value; } }
    public MatchNode(int size) { this.myField = new NodeVal[size]; }
}
var m = new MatchNode(10);
m[0] = new NodeVal();