views:

52

answers:

4

Hi all,

In a case where you would like to reset an array of boolean values what is faster, rediming the array or enumerating and resetting the values?

I have run some tests and they seem to suggest that a redim is a lot faster but I am not convinced that it isnt a result of how I’m running the tests.

My tests seem to suggest that redim is nearly twice as fast.

So could anyone care to comment on which is faster and why? Also would you expect the same result across different languages?

Enum Test:

Dim booleanArray(200) As Boolean

        Dim startTime As Date = Date.Now

        For i As Integer = 0 To 9999999
            For l As Integer = 0 To 200
                booleanArray(l) = True
            Next
        Next

        Dim endTime As Date = Date.Now

        Dim timeTaken As TimeSpan = endTime - startTime

Redim Test:

Dim booleanArray(200) As Boolean

        Dim startTime As Date = Date.Now

        For i As Integer = 0 To 9999999
            ReDim booleanArray(200)
        Next

        Dim endTime As Date = Date.Now

        Dim timeTaken As TimeSpan = endTime - startTime
A: 

I would expect the ReDim to be faster, as you are not assigning a value to each item of the array.

The micro benchmark appears OK.

Oded
It should clean up the array contents. `Redim Preserve` will retain the contents (as per my VB6 understanding).
shahkalpesh
@shahkalpesh - vb.net is not vb6, but the redim syntax is the same.
Oded
@Oded: Definitely. And they wouldn't change a statement's meaning.
shahkalpesh
+2  A: 

This shows that allocating a new array is fast. That's to be expected when there's plenty of memory available - basically it's incrementing a pointer and a tiny bit of housekeeping.

However, note that that will create a new array with all elements as False rather than True.

A more appropriate test might be to call Array.Clear on the existing array, in the first case, which will wipe out the contents pretty quickly.

Note that your second form will be creating a lot more garbage - in this case it will always stay in gen0 and be collected easily, but in real applications with more realistic memory usage, you could end up causing garbage collection performance issues by creating new arrays instead of clearing out the old ones.

Here's a quick benchmark in C# which tests the three strategies:

using System;
using System.Diagnostics;

public class Test
{
    const int Iterations = 100000000;

    static void Main()
    {
        TestStrategy(Clear);
        TestStrategy(ManualWipe);
        TestStrategy(CreateNew);
    }

    static void TestStrategy(Func<bool[], bool[]> strategy)
    {
        bool[] array = new bool[200];
        GC.Collect();
        GC.WaitForPendingFinalizers();
        Stopwatch sw = Stopwatch.StartNew();
        for (int i = 0; i < Iterations; i++)
        {
            array = strategy(array);
        }
        sw.Stop();
        Console.WriteLine("{0}: {1}ms", strategy.Method.Name,
                          (long) sw.ElapsedMilliseconds);
    }

    static bool[] Clear(bool[] original)
    {
        Array.Clear(original, 0, original.Length);
        return original;
    }

    static bool[] ManualWipe(bool[] original)
    {
        for (int i = 0; i < original.Length; i++)
        {
            original[i] = false;
        }
        return original;
    }

    static bool[] CreateNew(bool[] original)
    {
        return new bool[original.Length];
    }
}

Results:

Clear: 4910ms
ManualWipe: 19185ms
CreateNew: 2802ms

However, that's still just using generation 0 - I'd personally expect Clear to be better for overall application performance. Note that they behave differently if any other code has references to the original array - the "create new" strategy (ReDim) doesn't change the existing array at all.

Jon Skeet
ReDim does not preserve existing content... Redim Preserve does... Or do you mean that the content remains somewhere in memory?
Maxim Gershkovich
"If you do not specify `Preserve`, `ReDim` initializes the elements of the new array to the default value for their data type." http://msdn.microsoft.com/en-us/library/w8k3cys2(VS.80).aspx
MarkJ
Thanks Jon, dont know what we would do without your clear and detailed answers... :-)
Maxim Gershkovich
@Maxim: You mean *after* I screw up by getting the ReDim behaviour wrong? :)
Jon Skeet
+1  A: 

The tests aren't comparable.
The first test sets the each element to true, whereas Redim doesn't do that.

Redim helps you increase/decrease the bounds & clean up the content (and set it to default). e.g. Redim will help set the content of the boolean array to false.

Are you expecting Redim to set all the elements to true?

Dim booleanArray(200) As Boolean

For l As Integer = 0 To 200
   booleanArray(l) = True
Next

Redim booleanArray(200)

This will reset the content of each element of booleanArray to false.

If you want to retain the content & increase the size - Redim Preserve booleanArray(300) (instead of Redim booleanArray(200)). This will keep the first 200 elements to true and a new 100 elements will have default value (false).

shahkalpesh
+1  A: 

I have tested this in C# language 3.5

Time taken for Enum Test : 00:00:06.2656 Time taken for Redim Test: 00:00:00.0625000

As you can see Redim is a lot faster as you are not setting any values to it.

mohang