【发布时间】:2012-08-20 11:48:36
【问题描述】:
通常,我永远不必问自己给定的场景是否更适合结构或类,坦率地说,在这种情况下,我在上课之前没有问过这个问题。现在我正在优化,事情变得有点混乱。
我正在编写一个数字运算应用程序,用于处理包含数百万个 Base10 数字的超大数字。这些数字是 2D 空间中的 (x,y) 坐标。主要算法是相当连续的,并且在任何给定时间在内存中都没有超过 200 个 Cell 类的实例(如下所列)。该类的每个实例占用大约 5MB 的内存,导致应用程序的总峰值内存不超过 1GB。成品将在 16 核机器上运行,具有 20GB 的 RAM,并且没有其他应用程序占用资源。
这是课程:
// Inheritance is convenient but not absolutely necessary here.
public sealed class Cell: CellBase
{
// Will contain numbers with millions of digits (512KB on average).
public System.Numerics.BigInteger X = 0;
// Will contain numbers with millions of digits (512KB on average).
public System.Numerics.BigInteger Y = 0;
public double XLogD = 0D;
// Size of the array is roughly Base2Log(this.X).
public byte [] XBytes = null;
public double YLogD = 0D;
// Size of the array is roughly Base2Log(this.Y).
public byte [] YBytes = null;
// Tons of other properties for scientific calculations on X and Y.
// NOTE: 90% of the other fields and properties are structs (similar to BigInteger).
public Cell (System.Numerics.BigInteger x, System.Numerics.BigInteger y)
{
this.X = x;
this.XLogD = System.Numerics.BigInteger.Log(x, 2);
this.XBytes = x.ToByteArray();
this.Y = y;
this.YLogD = System.Numerics.BigInteger.Log(y, 2);
this.YBytes = y.ToByteArray();
}
}
我选择使用类而不是结构只是因为它“感觉”更自然。字段、方法和内存的数量都本能地指向类而不是结构。通过考虑临时分配调用会产生多少开销,我进一步证明了这一点,因为底层的主要对象是 BigInteger 的实例,而 BigInteger 本身就是一个结构。
问题是,考虑到速度效率是这种情况下的最终目标,我是否明智地选择了这里?
这里有一些关于算法的信息,以防万一。在每次迭代中:
- 对所有 200 个实例执行一次排序。 20% 的执行时间。
- 计算感兴趣的相邻 (x,y) 坐标。 60% 的执行时间。
- 上述第 2 点的并行/线程开销。 10% 的执行时间。
- 分支开销。 10% 的执行时间。
- 最昂贵的函数:BigInteger.ToByteArray() (implementation)。
【问题讨论】: