Although the ArrayList lost the calculation race, we expect that it will win the element insertion race, especially when we compare inserting a new element into a full array versus inserting a new element into a full ArrayList.
The problem with inserting into a full array is that we have to perform two operations to allow the insertion: First we must allocate more space to the array and then shift a set of array elements over one position to make room for the new element. For a small array, this is really not an issue, but for an array with many elements (such as our test array in the following program, with
one million elements) the time it takes to move up to one million elements to a new position can be prohibitive.
To test how prohibitive inserting into an array can be, we can set up an array with one million elements and insert an item into the 500,000th posi- tion. If the array is full, we’ll first have to allocate more space using Redim Preserve and then shift every element from 499,999 to 999,999 over one po- sition to make room for the new element. If the array isn’t full, we only have to perform the shifting, but in the code that follows we test the worst-case scenario.
Let’s start the test by examining the program: Option Strict On
Imports Timing Module Module1
Sub Main()
Dim nums(999999) As Integer Dim numsAList As New ArrayList Dim i As Integer
Dim arrTime As New Timing Dim arrListTime As New Timing For i = 0 To 999999 nums(i) = i Next For i = 0 To 999999 numsAList.Add(i) Next arrTime.startTime() InsertElement(nums, 499999, -1) arrTime.stopTime() arrListTime.startTime() numsAList.Insert(499999, -1) arrListTime.stopTime() Console.WriteLine()
Console.WriteLine("Array time: " & _
arrTime.Result.TotalMilliseconds) Console.WriteLine()
Console.WriteLine("ArrayList time: " & _ arrListTime.Result.TotalMilliseconds)
Comparing Arrays to ArrayLists 69
Console.Read() End Sub
Sub InsertElement(ByVal arr() As Integer, ByVal pos _ As Integer, ByVal item As Integer) Dim index As Integer
If (arr(pos) <> 0) And arr(arr.GetUpperBound(0)) _ <> 0 Then
ReDim Preserve arr(CInt(arr.Length * 1.25)) ShiftDown(arr, pos)
arr(pos) = item
ElseIf (arr(pos) <> 0) Then ShiftDown(arr, pos) arr(pos) = item Else arr(pos) = item End If End Sub
Sub ShiftDown(ByVal arr() As Integer, ByVal pos _ As Integer)
Dim index As Integer
For index = pos To arr.Length - 2 arr(pos + 1) = arr(pos)
Next End Sub End Module
The two subroutines—InsertElement and ShiftDown—perform the hard work. InsertElement first checks to see whether there is an element in the insertion position and whether the array is full and more space is required. If so, then Redim Preserve is called and the size of the array is increased by 25%. The ShiftDown routine is then called to make room for the new element and, finally, the new element is inserted into the array.
If the array isn’t full but there is an element in the insertion position, then only the ShiftDown subroutine is called. Otherwise, the element is simply inserted into the requested position.
The ShiftDown subroutine loops through the array, moving array elements from one position to the next position in the index. The only tricky part of
the code involves the For loop. This loop has to stop two positions before the end of the array or an exception will be thrown because the index will be out of bounds.
Here are the results from running this test:
The 20-second difference between the standard array and the ArrrayList is consistent over several runs of the program. These results clearly show the advantage of using an ArrayList over an array when numerous elements and insertions into the middle of the data must be performed.
SUMMARY
The array is the most commonly used data structure in computer program- ming. Most, if not all, computer languages provide some type of built-in array. For many applications, the array is the easiest data structure to implement and the most efficient. Arrays are useful in situations where you need direct access to “far-away” elements of your data set.
In many programming languages, arrays are not always the best structures to use if the size of the data is likely to change. In VB.NET, however, arrays can be dynamically resized, so this issue does not arise (though some overhead is involved).
The .NET Framework introduces a new type of array called an ArrayList. ArrayLists have many of the features of the array, but they are somewhat more powerful because they can resize themselves when the current capacity of the structure is full. The ArrayList also has several useful methods for performing insertions, deletions, and searches.
The chapter ended with a comparison of arrays and ArrayLists. The com- parison revealed that an array is faster for calculating whereas ArrayLists are faster for inserting elements. One conclusion that can be reached from these tests is that arrays are probably the best structure to use when working strictly with numeric values, whereas ArrayLists are more useful when dealing with
Exercises 71
nonnumeric data. However, if the data set you are working with is tabular in nature then you will need to use a two-dimensional array.
EXERCISES
1. Design and implement a class that allows a teacher to track the grades in a single course. Include methods that calculate the average grade, the highest grade, and the lowest grade. Write a program to test your class implementation.
2. Modify Exercise 1 so that the class can keep track of multiple courses. Write a program to test your implementation.
3. Rewrite Exercise 1 using an ArrayList. Write a program to test your imple- mentation and compare its performance to that of the array implementation in Exercise 1 using the Timing class.
4. Design and implement a class that uses an array to mimic the behavior of the ArrayList class. Include as many methods from the ArrayList class as possible. Write a program to test your implementation.