我需要处理大约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
是否使用正确的数据类型?数据点是钱......
谢谢! 布赖恩
答案 0 :(得分:4)
如果您正在同时处理A,B,C,D,那么结构数组方法应该具有更好的空间局部性 - 由于数据聚集在一起,它将被分页到内存中并且同时(页面更少)故障)并同时提取到CPU缓存中。如果你处理所有的A,然后处理所有的B等,那么相反的情况就是如此,你应该使用数组数组。
如果不是非常困难,我建议您尝试两种选择并测量并看看哪种更好。如果这太难了,请使用哪种方法更简单易懂,然后进行衡量,看它是否符合您的绩效目标。
答案 1 :(得分:2)
关于使用二维数组的上一篇文章的一个评论:
数组数组(有时称为锯齿状数组)提供比二维数组更好的性能,因为二维地址转换需要乘法和加法,而锯齿状数组只需要两次加法。
当然差异只会出现在数百万次观看之后。
答案 2 :(得分:1)
请注意,当您处理结构数组时,单个结构元素(特别是因为您将每个值作为属性)将需要被视为单个不可变对象。这意味着,如果要在数组元素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位(或总线宽度),数据加载所需的时间就越短。
希望这有帮助!