web-dev-qa-db-ja.com

アイテムを配列に追加する最速の方法

既存のアレイに新しいアイテムを追加する最速の方法は何ですか?

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

(アイテムの動的リストを操作する場合は、ListArrayList、または同様の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)アイテムが追加されるたびに、配列全体の2つの変換が行われるため、非常に遅いようです。 B)より高速に見えますが、ReDim Preserve。 C)この時点で最速のようです。もっと良いものはありますか?

22
jor

ケース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
37
jor

次に何がわからない人のために、新しいモジュールファイルを追加し、@ jorコード(私のハッキングされた、 'nothing'配列をサポートする)を下に配置するだけです。

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
8
Eric F.
Dim arr As Integer() = {1, 2, 3}
Dim newItem As Integer = 4
ReDim Preserve arr (3)
arr(3)=newItem

詳細については Redim

7

あまりきれいではありませんが、動作します:)

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

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

挿入または読み取りの頻度によって異なります。必要に応じて、配列を複数増やすことができます。

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

時間があれば、すべてをリストに変換し、配列を削除することをお勧めします。

*コードがコンパイルされない場合があります

0
the_lotus