2013-08-07 3 views
20

기존 배열에 새 항목을 추가하는 가장 빠른 방법은 무엇입니까?배열에 항목을 추가하는 가장 빠른 방법

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)이 시점에서 가장 빠른 것 같습니다. 더 좋은 점이 있습니까? 추가 정보를

+0

작동하지, 난 당신이 망고와 사과를 비교하는 생각 : 아무도 첫 번째 대안을 사용하지 않을 것입니다. 목록의 장점 중 하나는 새 항목을 빠르게 추가 할 수 있다는 것입니다 (배열로 변환하지 않고 항목을 추가하면 다른 대안보다 훨씬 빠름을 알 수 있습니다). 항목을 빠르게 추가하는 것에 관심이 있습니다. 목록을 사용하십시오 (배열에 전혀 의존하지 마십시오). 또한 배열을 허용하는 것보다 더 많은 옵션을 사용하여 항목을 검사/색인 할 수 있습니다. 하지만 순수한 성능 (예를 들어, 루프 내에서) 이외에는 훨씬 더 악화되어 있습니다. – varocarbas

+3

요약 : 최상의 상황에서 배열과 목록을 사용하십시오. VB.NET은 재 치수를 재 지정할 수 있지만 배열이 통과 할 것으로 예상되는 것은 아닙니다. 배열은 요소 내에서 반복되는 고정 된 크기의 조건에서 최상의 성능을 제공합니다. 반면에, List는 요소의 수가 적고, 차원의 규칙적인 변경, 요소에 액세스하기위한 멋진 쿼리 등이 덜 반복적 인 처리를위한 것입니다.이 모든 것은 배열이 그렇게 좋지 않은 함수입니다. 따라서 고정 크기 조건에서의 성능을위한 배열; 변화하는 조건을 나열합니다. – varocarbas

+0

추 신 : 목록은 메모리 효율이 떨어집니다. – varocarbas

답변

33

사례 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 

사용법 : 다음, 단지 새로운 모듈 파일을 추가 할 것을 알고, 내 작은 해킹과 (지원 '을 @jor 코드를 삽입하지 않은 사람들을 위해

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 
+0

Array.Resize (arr, arr.Length + 1) 여야합니다. –

+0

@JimThio : 네 말이 맞아 - 고마워! 코드 스 니펫을 업데이트했습니다. – jor

+0

다음에 무엇을 알지 못하는 사람들을 위해 새로운 모듈 파일을 추가하고 @jor 코드를 삽입하십시오 (제 해킹 된, 지원되지 않는 '아무것도'배열이 아님). + ---- 편집 됨, 코드가 뒤죽박죽입니다. 아래 내 대답을 참조하십시오. –

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

Redim

+4

기술적으로 말하면, ReDim Preserve arr (3)이라고 써야합니다. 그렇지 않으면 배열의 크기가 1보다 커집니다. 개인적으로 이것에 대해 너무 신경 쓰지 만 (나는 거의 매번 차원 배열을 하나씩 늘린다), 이것이 더 적절한 대답이 될 것이라고 나는 생각한다. – varocarbas

+0

배열이 3 개 항목으로 초기화되었으며 크기가 4가되도록 하나 이상의 항목을 추가하려고합니다. –

+1

예,하지만 ReDim Preserve arr (4)는 4의 크기를 나타내지 않고 4의 가장 높은 색인 즉 5의 크기를 나타냅니다. 말씀 드렸듯이 나는이 정면에서 내가 아는 한 수업을하지 않아야합니다. 항상 당신이하는 일을하고 있지만, 이론적으로 말해서, 정확하지는 않습니다. – varocarbas

0

그것은 당신이 삽입 또는 읽기 빈도에 따라 달라집니다. 필요한 경우 배열을 둘 이상 늘릴 수 있습니다.

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 

시간이있는 경우 목록으로 모두 변환하고 배열을 제거하는 것이 좋습니다.

* 내 코드가 컴파일되지 않을 수 있습니다.

8

아무것도 없음 '배열).

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 
4

매우 깨끗하지만이 때문에 관하여 :

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

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