Самый быстрый способ добавить элемент в массив
каков самый быстрый способ добавить новый элемент в существующий массив?
Dim arr As Integer() = {1, 2, 3}
Dim newItem As Integer = 4
(Я уже знаю, что при работе с динамическим списком предметов, которые вы должны использовать List
, ArrayList
или подобное IEnumerables
. Но что делать, если вы застряли в устаревшем коде, который использует массивы?)
что я пробовал до сих пор:
' 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) кажется очень медленным, так как каждый раз, когда добавляется элемент, выполняются два преобразования всего массива. B) кажется быстрее, но все же массив скопировано один раз во время ReDim Preserve
. C) на данный момент, кажется, самый быстрый. Есть что-нибудь получше?
5 ответов
случай C) самый быстрый. Имея это как расширение:
Public Module MyExtensions
<Extension()> _
Public Sub Add(Of T)(ByRef arr As T(), item As T)
Array.Resize(arr, arr.Length + 1)
arr(arr.Length - 1) = item
End Sub
End Module
использование:
Dim arr As Integer() = {1, 2, 3}
Dim newItem As Integer = 4
arr.Add(newItem)
' --> duration for adding 100.000 items: 1 msec
' --> duration for adding 100.000.000 items: 1168 msec
для тех, кто не знал, что дальше, просто добавьте новый файл модуля и поместите @jor-код (с моим маленьким взломанным, поддерживающим массив "ничего") ниже.
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
Dim arr As Integer() = {1, 2, 3}
Dim newItem As Integer = 4
ReDim Preserve arr (3)
arr(3)=newItem
дополнительная информация вместо
Не очень чистый, но это работает :)
Dim arr As Integer() = {1, 2, 3}
Dim newItem As Integer = 4
arr = arr.Concat({newItem}).ToArray
Это зависит от того, как часто вы вставляете или читать. При необходимости можно увеличить массив более чем на один.
numberOfItems = ??
' ...
If numberOfItems+1 >= arr.Length Then
Array.Resize(arr, arr.Length + 10)
End If
arr(numberOfItems) = newItem
numberOfItems += 1
также для A вам нужно только получить массив, если это необходимо.
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
Если у вас есть время, я предлагаю вам преобразовать все это в список и удаление массивов.
* мой код может не компилироваться