繁体   English   中英

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

[英]Allocate array in the same object as class

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

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]

要么

matchNode[i]

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

编辑:正如瑞安(Ryan)所建议的那样,我似乎应该对动机进行更多的解释:

MatchNode类在项目中大量使用。 在项目中使用了数以百万计的文件,并且每次都访问了数百次,因此使它们尽可能紧凑和简洁可以减少缓存丢失和总体性能。

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

这些对象用在项目的瓶颈中,因此是否可以进一步优化它们很重要。

当然,我们可以拥有一个非常大的NodeVal数组,并只在MatchNode中保存一个索引,该索引可以定位实际数据,但同样,它将改变使用MatchNode的每个客户端代码,更不用说是一个肮脏的非面向对象的解决方案了。

杂乱的MatchNode可以使用各种不安全的技巧,例如不安全或静态的缓存代码,这是可以的 不能将这些优化泄漏给客户端代码。

您正在寻找索引器

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();

但是,我怀疑这会以任何方式影响性能(至少在速度方面),因此您应该使用性能分析工具(例如dotTrace)考虑实际问题。 此外,这种方法还将创建一个私有的后备场,它将产生相同的内存占用量。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM