arrays - una - que significa en matlab
La forma más rápida de agregar un elemento a una matriz (5)
¿Cuál es la forma más rápida de agregar un nuevo elemento a una matriz existente?
Dim arr As Integer() = {1, 2, 3}
Dim newItem As Integer = 4
(Ya sé que cuando se trabaja con una lista dinámica de elementos, se debe usar una List
, ArrayList
o IEnumerables
similares. ¿Pero qué hacer si se está atado al código heredado que usa matrices?)
Lo que he intentado hasta ahora:
'' 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) parece muy lento ya que cada vez que se agrega un elemento, se realizan dos conversiones de toda la matriz. B) parece más rápido, pero aun así la matriz se copia una vez durante ReDim Preserve
. C) parece ser el más rápido en este punto. ¿Hay algo mejor?
Caso C) es el más rápido. Teniendo esto como una extensión:
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
Uso:
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
Depende de la frecuencia con la que inserte o lea. Puede aumentar la matriz en más de uno si es necesario.
numberOfItems = ??
'' ...
If numberOfItems+1 >= arr.Length Then
Array.Resize(arr, arr.Length + 10)
End If
arr(numberOfItems) = newItem
numberOfItems += 1
También para A, solo necesita obtener la matriz si es necesario.
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
Si tiene tiempo, le sugiero que lo convierta todo en Lista y elimine matrices.
* Mi código podría no compilarse
No muy limpio, pero funciona :)
Dim arr As Integer() = {1, 2, 3}
Dim newItem As Integer = 4
arr = arr.Concat({newItem}).ToArray
Para aquellos que no sabían qué hacer a continuación, solo agreguen un nuevo archivo de módulo y pongan el código de @jor (con mi pequeño hackeo, soportando ''nada'') debajo.
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
para más información Redim