[arrays] Fastest way to add an Item to an Array

What is the fastest way to add a new item to an existing array?

Dim arr As Integer() = {1, 2, 3}
Dim newItem As Integer = 4

(I already know that when working with dynamic list of items you should rather use a List, ArrayList or similar IEnumerables. But what to do if you're stuck to legacy code that uses arrays?)

What I've tried so far:

' A) converting to List, add item and convert back
Dim list As List(Of Integer)(arr)
list.Add(newItem)
arr = list.ToArray()
' --> duration for adding 100.000 items: 33270 msec

' B) redim array and add item
ReDim Preserve arr(arr.Length)
arr(arr.Length - 1) = newItem
' --> duration for adding 100.000 items: 9237 msec

' C) using Array.Resize
Array.Resize(arr, arr.Length + 1)
arr(arr.Length - 1) = newItem
' --> duration for adding 100.000 items: 1 msec
' --> duration for adding 100.000.000 items: 1168 msec

A) seems very slow since every time an item is added two conversions of the whole array are done. B) seems faster but still the array is copied once during the ReDim Preserve. C) seems to be the fastest at this point. Is there anything better?

This question is related to arrays vb.net dynamic-arrays

The answer is


Not very clean but it works :)

Dim arr As Integer() = {1, 2, 3}
Dim newItem As Integer = 4

arr = arr.Concat({newItem}).ToArray

Dim arr As Integer() = {1, 2, 3}
Dim newItem As Integer = 4
ReDim Preserve arr (3)
arr(3)=newItem

for more info Redim


It depends on how often you insert or read. You can increase the array by more than one if needed.

numberOfItems = ??

' ...

If numberOfItems+1 >= arr.Length Then
    Array.Resize(arr, arr.Length + 10)
End If

arr(numberOfItems) = newItem
numberOfItems += 1

Also for A, you only need to get the array if needed.

Dim list As List(Of Integer)(arr) ' Do this only once, keep a reference to the list
                                  ' If you create a new List everything you add an item then this will never be fast

'...

list.Add(newItem)
arrayWasModified = True

' ...

Function GetArray()

    If arrayWasModified Then
        arr = list.ToArray()
    End If

    Return Arr
End Function

If you have the time, I suggest you convert it all to List and remove arrays.

* My code might not compile


For those who didn't know what next, just add new module file and put @jor code (with my little hacked, supporting 'nothing' array) below.

Module ArrayExtension
    <Extension()> _
    Public Sub Add(Of T)(ByRef arr As T(), item As T)
        If arr IsNot Nothing Then
            Array.Resize(arr, arr.Length + 1)
            arr(arr.Length - 1) = item
        Else
            ReDim arr(0)
            arr(0) = item
        End If

    End Sub
End Module