2013-08-07 41 views
20

Cách nhanh nhất để thêm một mục mới vào một mảng hiện có là gì?Cách nhanh nhất để thêm một mục vào một mảng

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

(tôi đã biết rằng khi làm việc với danh sách năng động của các bạn chứ không nên sử dụng một List, ArrayList hoặc tương tự IEnumerables. Nhưng phải làm gì nếu bạn đang mắc kẹt với mã di sản mà sử dụng mảng?)

những gì tôi đã cố gắng cho đến nay:

' 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) có vẻ rất chậm vì mỗi lần một mục được bổ sung thêm hai chuyển đổi của toàn bộ mảng được thực hiện. B) có vẻ nhanh hơn nhưng mảng vẫn được sao chép một lần trong ReDim Preserve. C) có vẻ là nhanh nhất vào thời điểm này. Có điều gì tốt hơn không?

+0

Với sự tôn trọng, tôi nghĩ rằng bạn đang so sánh táo với xoài: ai sẽ không bao giờ sử dụng thay thế đầu tiên của bạn. Một trong những ưu điểm của danh sách là tốc độ bạn có thể thêm các mục mới vào nó (nếu bạn không thực hiện chuyển đổi thành mảng, chỉ cần thêm mục, bạn sẽ thấy rằng nó nhanh hơn nhiều so với bất kỳ phương án nào khác): nếu bạn chỉ quan tâm đến việc thêm các mục một cách nhanh chóng, sử dụng một danh sách (không dựa vào một mảng nào cả). Ngoài ra danh sách cho phép nhiều tùy chọn hơn để kiểm tra/chỉ mục các mục của nó so với những gì mảng cho phép. NHƯNG khác hơn thế, trong hiệu suất thuần túy (trong vòng lặp, ví dụ), chúng tệ hơn nhiều ... – varocarbas

+3

Tóm tắt: sử dụng mảng và danh sách trong các tình huống tốt nhất. Mặc dù VB.NET cho phép redimensioning, đây không phải là những gì một mảng được mong đợi để đi qua: mảng cung cấp hiệu suất tốt nhất trong điều kiện kích thước cố định, chỉ cần lặp đi lặp lại nhiều lần trong các phần tử của nó. Mặt khác, các danh sách có nghĩa là điều trị ít lặp đi lặp lại: số lượng yếu tố thấp hơn, thay đổi thường xuyên về kích thước, truy vấn ưa thích để truy cập các phần tử, v.v. tất cả đều là các hàm mà mảng không tốt lắm. Vì vậy, mảng cho hiệu suất dưới điều kiện có kích thước cố định; Danh sách để thay đổi điều kiện. – varocarbas

+0

PS: Danh sách cũng ít hiệu quả về bộ nhớ hơn. – varocarbas

Trả lời

33

Trường hợp C) là nhanh nhất. Có điều này như một phần mở rộng:

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 

Cách sử dụng:

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

nó nên được Array.Resize (arr, arr.Length + 1) Tôi đã thử. –

+0

@JimThio: bạn nói đúng - cảm ơn! Tôi đã cập nhật đoạn mã. – jor

+0

Đối với những người không biết điều gì tiếp theo, chỉ cần thêm tệp mô-đun mới và đặt mã @jor (với ít bị tấn công của tôi, hỗ trợ mảng 'không có gì') bên dưới. + ---- Đã chỉnh sửa, mã bị xáo trộn. Đi xem câu trả lời của tôi dưới đây. –

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

để biết thêm Redim

+4

Về mặt kỹ thuật, bạn nên viết: ReDim Preserve arr (3), nếu không bạn đang quá kích thước mảng bằng 1. Cá nhân tôi không chăm sóc quá nhiều về điều này (tôi vượt qua mảng kích thước bởi một thời gian gần như mọi thời gian) nhưng tôi đoán rằng đây sẽ là một câu trả lời đúng đắn hơn. – varocarbas

+0

mảng đã được khởi tạo với 3 mục và họ muốn thêm một mục nữa để kích thước phải là 4 không phải là nó? –

+1

Có, nhưng ReDim Preserve arr (4) không cho biết kích thước 4 nhưng chỉ số cao nhất là 4, có nghĩa là, kích thước của 5. Như đã nói, tôi không nên đưa ra bài học về mặt trận này theo như tôi luôn luôn làm những gì bạn làm nhưng, về mặt lý thuyết, là không chính xác. – varocarbas

0

Nó phụ thuộc vào mức độ thường xuyên bạn chèn hoặc đọc. Bạn có thể tăng mảng nhiều hơn một nếu cần.

numberOfItems = ?? 

' ... 

If numberOfItems+1 >= arr.Length Then 
    Array.Resize(arr, arr.Length + 10) 
End If 

arr(numberOfItems) = newItem 
numberOfItems += 1 

Cũng cho A, bạn chỉ cần nhận mảng nếu cần.

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 

Nếu bạn có thời gian, tôi khuyên bạn nên chuyển đổi tất cả thành Danh sách và xóa mảng.

* Mã của tôi có thể không biên dịch

8

Đối với những người không biết chuyện gì tiếp theo, chỉ cần thêm tập tin mô-đun mới và đặt @jor mã (với hack nhỏ của tôi, hỗ trợ " không có gì 'mảng' bên dưới.

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

Not very clean nhưng nó hoạt động :)

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

arr = arr.Concat({newItem}).ToArray 
Các vấn đề liên quan