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.
精彩评论