开发者

Redim boolean Array vs enumerate and set

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 9开发者_如何转开发999999
            ReDim booleanArray(200)
        Next

        Dim endTime As Date = Date.Now

        Dim timeTaken As TimeSpan = endTime - startTime


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.


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).


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.


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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜