Vs类纯阵列表示

Kas*_*dum 0 c# arrays performance code-design

我们需要在我们的应用程序中代表大量数字.我们使用整数数组来做这个.最终的生产应该是性能最大化.我们考虑将数组封装在一个类中,这样我们就可以添加与数组相关的属性,如isNegative,numberBase等.

但是,我们担心使用课程会使我们的表现明智.我们做了一个测试,我们创建了一个固定数量的数组,并通过纯数组使用设置它的值,并创建一个类,并通过类访问数组:

for (int i = 0; i < 10000; i++)
{
    if (createClass)
    {
        BigNumber b = new BigNumber(new int[5000], 10);
        for (int j = 0; j < b.Number.Length; j++)
        {
            b[j] = 5;
        }
    }
    else
    {
        int[] test = new int[5000];
        for (int j = 0; j < test.Length; j++)
        {
            test[j] = 5;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

并且似乎使用类几乎将上述代码的运行时间减慢了6倍.我们通过将数组封装在结构中来尝试上述操作,这导致运行时间几乎等于纯数组使用.

与结构相比,使用类时导致这种巨大开销的原因是什么?当你使用堆栈而不是堆时,它真的只是你获得的性能提升吗?

编辑: BigNumber只将数组存储在属性公开的私有变量中.简化:

public class BigNumber{
  private int[] number;

  public BigNumber(int[] number) { this.number = number;}

  public int[] Number{get{return number;}}
}
Run Code Online (Sandbox Code Playgroud)

Guf*_*ffa 5

第二个循环比第一个循环快得多并不奇怪.发生的事情不是该类非常慢,而是循环对于编译器来说非常容易优化.

由于循环范围从0到test.Length-1,编译器可以告诉索引变量永远不会在数组之外,因此它可以在通过索引访问数组时删除范围检查.

在第一个循环中,编译器无法在循环和数组之间建立连接,因此必须根据访问的每个项的边界检查索引.

将数组封装在类中时,总会有一些开销,但它并不像测试中的差异那么大.您已经选择了一个引用程序,其中编译器能够非常好地优化普通数组访问,因此您正在测试的是编译器优化代码的能力,而不是您打算测试的内容.

  • @Qua:如果使用结构获得相同的性能,则可以通过编译器直接访问数组的方式公开数组。如果没有看到相关代码,很难确切地说出原因。您发布的 BigNumber 类的简化代码不包含您在测试代码中使用的索引器,或者您发布的测试代码可能不是实际使用的代码... (2认同)