Самый быстрый способ добавить элемент в массив
Каков самый быстрый способ добавить новый элемент в существующий массив?
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) кажется самым быстрым на данный момент. Что-нибудь лучше?
Ответы
Ответ 1
Случай 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
Ответ 2
Для тех, кто не знал, что дальше, просто добавьте новый файл модуля и поместите код @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
Ответ 3
Dim arr As Integer() = {1, 2, 3}
Dim newItem As Integer = 4
ReDim Preserve arr (3)
arr(3)=newItem
для дополнительной информации Redim
Ответ 4
Не очень чистый, но он работает:)
Dim arr As Integer() = {1, 2, 3}
Dim newItem As Integer = 4
arr = arr.Concat({newItem}).ToArray
Ответ 5
Это зависит от того, как часто вы вставляете или читаете. Вы можете увеличить массив более чем на один, если необходимо.
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
Если у вас есть время, я предлагаю вам преобразовать все его в список и удалить массивы.
* Мой код не может компилироваться