2013-08-07 28 views
20

Varolan diziye yeni bir öğe eklemenin en hızlı yolu nedir?Bir Diziye Öğe eklemenin en hızlı yolu

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

(Zaten öğelerin dinamik listesi ile çalışırken oldukça kullanması gerektiğini biliyorum bir List, ArrayList veya benzeri IEnumerables. Eğer diziler kullanan eski koduna takılıp Ama ne yapmalı?)

Şimdiye kadar denedim ne

:

' 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) bir öğe bütün dizinin iki dönüşüm eklenen her zaman yapılır beri çok yavaş görünüyor. B) daha hızlı görünüyor ama hala dizi ReDim Preserve sırasında bir kez kopyalanır. C) bu noktada en hızlı gibi görünüyor. Daha iyi bir şey var mı? Daha fazla bilgi için

+0

çalışır değil, sana mango ile elma karşılaştırma olduğunu düşünüyorum: kimse ilk alternatif kullanmak ister. Bir listenin avantajlarından biri, yeni öğeleri ne kadar hızlı ekleyebileceğinizdir (diziye dönüştürme işlemini yapmazsanız, öğeyi ekleyin, diğer alternatiflerden daha hızlı olduğunu görürsünüz): Sadece hızlı bir şekilde öğe eklemekle ilgilenir, bir liste kullanır (hiç bir diziye güvenmeyin). Ayrıca liste, öğelerin, dizilerin izin verdiğinden daha fazla denetlenmesini/endekslenmesini sağlar. AMA bundan başka, saf performansta (örneğin döngüler içinde), çok daha kötüler ... – varocarbas

+3

Özet: en iyi durumlarda dizileri ve listeleri kullanın. VB.NET'in yeniden boyutlandırmaya izin vermesine rağmen, bu bir dizinin geçmesi beklenen bir şey değildir: diziler, sabit boyutlu koşullar altında en iyi performansı sunar, sadece kendi öğeleri içinde tekrar tekrar tekrar ortaya çıkar. Diğer taraftan, listeler daha az yinelemeli bir tedavi içindir: daha az sayıda eleman, boyutlarda düzenli değişiklikler, elemanlara erişmek için fantezi sorgular, vb. Tüm bunlar dizilerin çok iyi olmadığı fonksiyonlardır. Böylece, sabit büyüklükteki koşullar altında performans için Diziler; Koşulları değiştirmek için listeler. – varocarbas

+0

PS: Listeler daha az bellek verimli. – varocarbas

cevap

33

Senaryo C derlemek olmayabilir Kodum hızlı olduğunu. bir uzantısı olarak bu Having:

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 

Kullanımı: Bir sonraki, sadece yeni modül dosyası eklemek biliyorum ve benim küçük saldırıya uğramış ile (destekleyici '@jor kodu koymadı olanlar için

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 olmalıdır (arr, arr.Length + 1) Denedim. –

+0

@JimThio: Haklısın - teşekkürler! Kod snippet'ini güncelledim. – jor

+0

Sırada ne olduğunu bilmeyenler için, sadece yeni modül dosyası ekleyip @jor kodunu (küçük hackledim, 'hiçbir şey' dizisini destekleyerek) koy. + ---- Düzenlendi, kod karışık. Git cevabımı aşağıya bakın. –

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

Redim

+4

Teknik olarak şunu söylemiş olmalısınız: ReDim Korunması arr (3), aksi takdirde diziyi 1 ile aşırı boyutlandırıyorsunuz. Bu konuda çok fazla özen gösteriyorum (neredeyse her zaman bir aşırı boyut dizisi) ama bunun daha doğru bir cevap olacağını düşünüyorum. – varocarbas

+0

dizisi 3 öğe ile başlatıldı ve bir tane daha öğe eklemek istiyorlar, böylece boyut 4 olmalı? –

+1

Evet, fakat ReDim Korunması arr (4) 4'lük bir boyutu değil, 4'lük bir en yüksek endeksi, yani 5'lik bir boyutu göstermez. Dediğim gibi, bu cephede dersler vermemeliyim. Her zaman yaptığınız şeyi yapmak, ancak teorik olarak konuşmak doğru değildir. – varocarbas

0

Sizin eklemek veya okumak ne sıklıkta bağlıdır. Diziyi gerektiğinde birden fazla arttırabilirsiniz.

numberOfItems = ?? 

' ... 

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

arr(numberOfItems) = newItem 
numberOfItems += 1 

Ayrıca A için, gerekirse diziyi almanız gerekir. Zamanınız varsa

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 

, sana her Liste ve diziler kaldırmak dönüştürmek öneririz.

*)

8

hiçbir şey 'dizi) aşağıda.

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

çok temiz ama Saygısızlık :)

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

arr = arr.Concat({newItem}).ToArray 
İlgili konular