c#中小数组与小结构的访问时间

时间:2009-08-20 17:24:32

标签: c# arrays struct

我需要处理大约500,000个数据点,每个数据点包含4位小数。我想使用和数组结构来做到这一点。这会比使用数组数组慢得多吗?看起来内存不会成为问题,但速度会 - 它需要快速。

两个选项的快速代码示例:

选项1:

public struct Struct
{
    public decimal A { get; set; }
    public decimal B { get; set; }
    public decimal C { get; set; }
    public decimal D { get; set; }
}

用法:

private Struct[] data;

选项2:

private decimal [][] data;

另外,decimal是否使用正确的数据类型?数据点是钱......

谢谢! 布赖恩

6 个答案:

答案 0 :(得分:4)

如果您正在同时处理A,B,C,D,那么结构数组方法应该具有更好的空间局部性 - 由于数据聚集在一起,它将被分页到内存中并且同时(页面更少)故障)并同时提取到CPU缓存中。如果你处理所有的A,然后处理所有的B等,那么相反的情况就是如此,你应该使用数组数组。

如果不是非常困难,我建议您尝试两种选择并测量并看看哪种更好。如果这太难了,请使用哪种方法更简单易懂,然后进行衡量,看它是否符合您的绩效目标。

答案 1 :(得分:2)

关于使用二维数组的上一篇文章的一个评论:

数组数组(有时称为锯齿状数组)提供比二维数组更好的性能,因为二维地址转换需要乘法和加法,而锯齿状数组只需要两次加法。

当然差异只会出现在数百万次观看之后。

答案 2 :(得分:1)

  1. 如果您正在处理货币值,则十进制是正确使用的类型。
  2. 一系列结构将非常快。
  3. 请注意,当您处理结构数组时,单个结构元素(特别是因为您将每个值作为属性)将需要被视为单个不可变对象。这意味着,如果要在数组元素4中更改C,则需要执行以下操作:

    MyStruct val = array[5];
    val.C = newValue;
    array[5] = val;
    

    切换到公共字段可以减少其中的一部分,但会增加自己的问题。可变结构有时会使事情变得更复杂......

答案 3 :(得分:1)

嗯......如果用二维数组替换数组数组,结果内存布局应该或多或少相等:

private Struct[] data = new Struct[x];
private decimal[,] data = new decimal[x,4];

除非你希望将其中一个数组传递给其他方法......

答案 4 :(得分:1)

当处理金钱时,如果你进行比较或简单的加法和减法,使用整数通常更快,效率更高,而且不需要担心舍入错误。

答案 5 :(得分:1)

结构数组和锯齿状数组在内存中的布局方式大致相同,因此使用它时不会产生性能损失。

public struct Struct
{
    // Unless you're filling your get/set blocks with anything,
    // these properties will be in-lined in compilation time
    // and will have the same performance/behavior as using public fields

    public decimal A { get; set; }
    public decimal B { get; set; }
    public decimal C { get; set; }
    public decimal D { get; set; }
}

所以我考虑使用公共字段。但这只是我的意见,我想明确知道事情会如何表现。

关于使用小数来赚钱,这并非总是如此。十进制是一个128位数据字段,它具有非常高的精度,但它的整数部分具有窄范围的值。如果您需要高精度来计算速率或类似的东西,但您不需要非常高的值,请转到十进制。如果您需要更高的值而不是更高的精度,请选择加倍。如果你正在处理小值并且只需要相当大的精度,那就去浮动吧。

请记住,数据类型越接近32位(或总线宽度),数据加载所需的时间就越短。

希望这有帮助!