2010-05-26 192 views
1

是否存在调整矩形阵列大小的智能方法?调整矩形阵列的大小

double[,] temp = new double[newSize, originalSecondDimension]; 
Array.Copy(original, temp, original.Length); 

我担心重复一个巨大的数组和必要的内存来做到这一点。 Array.Resize()在内部做什么?

感谢,

阿尔贝托

回答

3

你应该推迟业绩微优化,直到一个地步,你实际测量和观察的问题。这就是说...

在.NET中调整数组的大小要求重新分配它们。 (通常)没有间隙地布置内存 - 因此,如果不将其移动到堆中的新位置,您就无法调整它的大小。

你通常不应该关心如何Resize()内部工作 - 但在这种情况下,the documentation居然明确地描述了发生的事情:

这种方法分配一个新的数组 指定大小,复制元素 从旧阵列到新阵列,然后 用 替换旧阵列。

请记住,.NET中的内存分配非常高效 - 它主要涉及将高水位标记指针移到堆的地址空间并清零内存。除非你正在分配一个非常大的数组,或者在一个紧密的循环中反复这样做,否则你不可能遇到问题。

在您的情况下,确实没有更好的方式来调整多维数据的大小。但是 - 您应该强烈考虑将此行为封装在自定义类中。传递原始数组对象不是一个好主意 - 事情出错的方式太多了。尤其是,因为当调整大小时会有一个新的数组实例 - 这可能会破坏保留在旧数组实例引用上的任何代码,并假定它们仍然有效。

您始终可以创建一个提供索引器属性的类,并且具有多维数组的语法“外观和感觉”,而不会实际暴露其中一个。不幸的是,据我所知,.NET类库中没有内置的多维集合类。但是,编写一个简单的包装应该不会太难。顺便说一句,如果你真的关心性能,你应该知道,.NET多维数组知道执行速度比一维甚至锯齿状数组慢(double[][])。

+1

有一点要提到,但是......不,没有更好的方法来处理多维数据。 – AxelEckenberger 2010-05-26 13:27:55

+0

你可以有一个集合 – 2010-05-26 13:38:26

+0

@Joel Coehoorn:当然,*但我仍然会编写一个包装类来控制所需的语义*。例如,如果一个集合的大小可能大于其他集合(例如锯齿形数组或集合集合),则可能会出现问题。只有OP知道他需要什么 - 但封装你想要的行为绝不是一个坏主意 - 而不是在代码中的多个地方传播知识和规则。 – LBushkin 2010-05-26 13:41:55

2

是的,有一个更明智的方法:不要使用数组!如果您发现自己需要重新调整大小的数组,则应该使用集合类型。

+0

取决于。如果实现一个数学模型(其中的算法是使用向量,矩阵,超立方体等定义的),.NET数组可以是存储数据的最佳/最有效的方式。即使他们需要一个封装类,以便于使用。 – CuppM 2010-05-26 14:19:08

1

我的猜测是你不能。阵列。调整()需要一个ref T[],这表明它的工作原理是这样的:

int[] a = new int[1]; 
int[] b = a; 
Array.Resize(b,2); 
Debug.Assert(a.Length == 1); 
Debug.Assert(b.Length == 2); 

如果阵列可以改变大小,然后在并行代码中,你不能优化掉边界检查,你不得不做一些事情每个访问来自大小的改变在你的脚下停止:

for (int i = 0; i < a.Length; i++) { sum += a[i]; } 

有可能是一个例外:它是理论上可以增加数组的大小提供的阵列不必被重新分配(内存对齐可能意味着就地调整字节大小[1]到字节[4]有可能)。然而,数组将被重新分配更为常见,所以没有必要担心这一点。

+0

'Resize()'的文档清楚地说明了它的工作方式:'这个方法分配一个指定大小的新数组,将旧数组中的元素复制到新数组中,然后用新数组替换旧数组。 – LBushkin 2010-05-26 14:20:34