Resizing a rectangular array
Does a smarter way than the following exist to resize a rectangular array?
double[,] temp = new double[newSize, originalSecondDimension];
Array.Copy(original, temp, original.Length);
I was concerned about duplicating a huge array and the memory necessary to do it. What does the A开发者_开发百科rray.Resize() do internally?
Thanks,
Alberto
You should defer performance micro-optimizations until a point where you actually measure and observe a problem. That said...
Resizing arrays in .NET requires them to be reallocated. Memory in a .NET process is (generally) laid out without gaps - so you cannot resize something like an array without moving it to a new location in the heap.
You normally should not care about how Resize()
works internally - but in this case, the documentation actually explicitly describes what happens:
This method allocates a new array with the specified size, copies elements from the old array to the new one, and then replaces the old array with the new one.
Keep in mind that memory allocation in .NET is quite efficient - it mostly involves moving a high-water mark pointer up the address space of the heap and zeroing out the memory. Unless you are allocating an unusually large array, or doing so over and over in a tight loop you are not likely to run into issues.
There's really no better way to resize multi-dimensional data, in your case. However - you should strongly consider encapsulating this behavior in a custom class. It's not a good idea to pass around raw array objects - there are too many ways for things to go wrong. Especially, since when resized there is a new array instance - which could break any code that holds on to references to the old array instance and assumes they are still valid.
You can always create a class that provides indexer properties and has the syntactic "look-and-feel" of a multidimensional array, without actually exposing one. Unfortunately, to my knowledge there are no built-in multi-dimensional collection classes in the .NET class library. However, writing a simple wrapper should not be too hard.
By the way, if you are truly concerned about performance, you should be aware that .NET multdimensional arrays are know to perform significalty slower than one dimensional and even jagged arrays (double[][]
).
Yes, there is a smarter way: Don't use an array! If you find yourself with an array that you need to re-size, you should be using a collection type instead.
My guess is that you can't. Array.Resize() takes a ref T[]
, suggesting that it works something like this:
int[] a = new int[1];
int[] b = a;
Array.Resize(b,2);
Debug.Assert(a.Length == 1);
Debug.Assert(b.Length == 2);
If arrays could change size, then in concurrent code, you couldn't optimize away bounds checks, and you'd have to do something for each access to stop it from changing size under your feet:
for (int i = 0; i < a.Length; i++) { sum += a[i]; }
There might be an exception: It's theoretically possible to increase the size of the array provided the array doesn't have to be reallocated (memory alignment probably means resizing byte[1] to byte[4] in-place should generally be possible). It's far more common that the array will be reallocated, though, so there's little point in worrying about this.
精彩评论