views:

209

answers:

1

Garbage collection in .NET leads many to believe that lightweight objects can be treated as temporary. This seems especially true of arrays that hold object references to objects that are instantiated outside of the context of the array initialization.

Consequently, it would seem that it should not really matter if a new array is initialized within an iteration of a state machine, particularly if that state blocks in any fashion, such as with a call to WaitHandle.WaitAny().

I would much rather create a new array as a lightweight container on-the-fly to hold my WaitHandle objects, than to resize the WaitHandle[] array using Array.Resize<T>().

Why? Well, assuming that memory is cheap and that Array.Resize<T>() will have to perform a memory allocation or a memory copy of some sort anyhow, it seems more efficient to simply implicitly discard the array by passing in a new one every time into the static method like this:

// using C# 3.0 array initialization syntax
eventIndex = WaitHandle.WaitAny(new[] { _stateStopEvent }, 5000);

(Check out this link for details on the array syntax)

_stateStopEvent is one of several potential events that may apply to any or all states, and those ManualResetEvent objects are declared at a higher scope, so it seems that managing the array is actually more work than it's worth.

Furthermore, if the code is declaring a temporary reference variable for the array and simply assigning a new array instance to it within each iteration of the state machine, what's the difference, from a performance perspective? Why not simply skip that step as shown in the code snippet above?

Is resizing the WaitHandle[] array by using Array.Resize<T>(), a better approach?

Taking byte[] arrays out of the picture, if I need to resize an array, wouldn't I just use a List or a Dictionary instance as is recommended here?

+1  A: 

This is what Array.Resize does:

[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
public static void Resize<T>(ref T[] array, int newSize)
{
    if (newSize < 0)
    {
        throw new ArgumentOutOfRangeException("newSize", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
    }
    T[] sourceArray = array;
    if (sourceArray == null)
    {
        array = new T[newSize];
    }
    else if (sourceArray.Length != newSize)
    {
        T[] destinationArray = new T[newSize];
        Copy(sourceArray, 0, destinationArray, 0, (sourceArray.Length > newSize) ? newSize : sourceArray.Length);
        array = destinationArray;
    }
}

So besides some range checking, it just creates a new array and copies the elements from the previous array to the new array.

Rauhotz
That's a lot of extra code for something I can achieve in this example in one line of code.
EnocNRoll