SORU
1 Mayıs 2011, Pazar


ArrayList Vs LinkedList

Diyor ki: bu previous post takip ediyordum

For LinkedList

    * get is O(n)
    * add is O(1)
    * remove is O(n)
    * Iterator.remove is O(1)

For ArrayList

    * get is O(1)
    * add is O(1) amortized, but O(n) worst-case since the array must be resized and copied
    * remove is O(n)

Bu bakarak, Eğer sadece 5000000 eleman söylemek için benim toplama sıralı ekleme yapmak istiyorum, LinkedList, ArrayList outclass olacağı sonucuna vardım.

Ve Eğer sadece ortadaki eleman kapma Değil yineleme yani toplama öğeleri almaya geldim, hala LinkedList, ArrayList outclass.

Şimdi yukarıda benim iki ifadeleri doğrulamak için, örnek program aşağıda yazdım... Ama yukarıdaki ifadelerim hatalı çıktı şaşırdım.

ArrayList outclass her iki durumda da Linkedlist. Ekleme gibi bir topluluktan çekici için LinkedList daha az zaman aldı. Yanlış yaptığım bir şey ya da LinkedList ve ArrayList hakkında ilk açıklamaları değil tutar boyutu 5000000 koleksiyonları için doğru mu?

Eğer 50000, LinkedList gerçekleştirmek daha iyi ve ilk açıklamalara elemanları sayısını azaltmak geçerlidir çünkü boyutu söz ettim.

long nano1 = System.nanoTime();

List<Integer> arr = new ArrayList();
for(int i=0;i<5000000;  i){
    arr.add(i);
}
System.out.println( (System.nanoTime() - nano1) );

for(int j: arr){
    ;
}
System.out.println( (System.nanoTime() - nano1) );

long nano2 = System.nanoTime();

List<Integer> arrL = new LinkedList();
for(int i=0;i<5000000;  i){
    arrL.add(i);
}
System.out.println( (System.nanoTime() - nano2) );

for(int j:arrL){
    ;
}
System.out.println( (System.nanoTime() - nano2) );

CEVAP
1 Mayıs 2011, Pazar


Büyük-O karmaşıklığı, asimptotik davranışı tanımlar ve gerçek uygulama hızı yansıtmıyor olabilir unutmayın. Her operasyonun maliyetini listesinin boyutunu, her bir işlem hızı ile büyüyor açıklar. Örneğin, add aşağıdaki uygulama O(1) olur ama hızlı değil:

public class MyList extends LinkedList {
    public void add(Object o) {
        Thread.sleep(10000);
        super.add(o);
    }
}

ArrayList adetle sınırla sayıda olmaz yani iç arabellek boyutu oldukça agresif bir şekilde artar, çünkü iyi performans senin durumunda sanıyorum. Tampon yeniden boyutlandırılabilir olması gerekmez ne zaman ArrayList var daha hızlı olacak adds.

Ayrıca profil oluşturma bu tür yaparken çok dikkatli olmak gerekir. İsterdim öneririm değiştirmek için profil oluşturma kodu için bir ısınma evresi (yani JİT var fırsat için bazı optimizasyon olmadan etkileyen sonuçları) ve ortalama sonuçlar üzerinde bir dizi çalışır.

private final static int WARMUP = 1000;
private final static int TEST = 1000;
private final static int SIZE = 500000;

public void perfTest() {
    // Warmup
    for (int i = 0; i < WARMUP;   i) {
        buildArrayList();
    }
    // Test
    long sum = 0;
    for (int i = 0; i < TEST;   i) {
        sum  = buildArrayList();
    }
    System.out.println("Average time to build array list: "   (sum / TEST));
}

public long buildArrayList() {
    long start = System.nanoTime();
    ArrayList a = new ArrayList();
    for (int i = 0; i < SIZE;   i) {
        a.add(i);
    }
    long end = System.nanoTime();
    return end - start;
}

... same for buildLinkedList

(sum taşma ve daha iyi kullanım için System.currentTimeMillis()) olabilir unutmayın.

Derleyici get boş döngüler optimize uzakta olması da muhtemel. Döngü aslında bir kod adı olduğundan emin olmak için emin olun.

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • ChrisCrossMedia

    ChrisCrossMe

    17 EYLÜL 2009
  • hockeywebcasts

    hockeywebcas

    31 EKİM 2012
  • ibebrent

    ibebrent

    23 Temmuz 2007