Yanıtlar:
Koleksiyondaki öğelerin sırası önemli olmadığında setler, koleksiyondaki öğeleri bulmak için daha iyi performans sunar.
Bunun nedeni, bir dizinin belirli bir nesneyi bulmak için tüm içeriğini yinelemek zorunda kalırken (bir sözlük gibi) öğeleri bulmak için karma değerleri kullanmasıdır.
Apple'ın Belgelerindeki görsel bunu çok iyi açıklıyor:
Array
Bir olan sıralı elemanları dizisi (ekleme sırasında sipariş korunur)
[array addObject:@1];
[array addObject:@2];
[array addObject:@3];
[array addObject:@4];
[array addObject:@6];
[array addObject:@4];
[array addObject:@1];
[array addObject:@2];
[1, 2, 3, 4, 6, 4, 1, 2]
Set
a, tat (hiçbir çiftleri), düzensiz elemanların listesi
[set addObject:@1];
[set addObject:@2];
[set addObject:@3];
[set addObject:@4];
[set addObject:@6];
[set addObject:@4];
[set addObject:@1];
[set addObject:@2];
[1, 2, 6, 4, 3]
Buna en iyi cevap, Apple'ın kendi belgeleridir .
Temel fark, NSArray
sıralı bir koleksiyon NSSet
için ve sırasız bir koleksiyon içindir.
Orada birkaç makale gibi ikisi arasındaki hız farkı, bahsedip duran vardır bu bir . Sırasız bir koleksiyonla yineleme yapıyorsanız NSSet
, harika. Bununla birlikte, çoğu durumda, yalnızca bir NSArray
kişinin yapabileceği şeyleri yapmanız gerekir , bu nedenle bu yetenekler için hızınızı feda edersiniz.
NSSet
NSArray
Gerçekten hepsi bu kadar! Yardımcı olacaksa bana haber ver.
NSSet
İndeksleme uğruna her zaman fedakarlık yapmanız gerekmez . Aynı veriler için iki farklı veri yapısı kullanmak yaygındır. Ya da o diziyi oluşturur ve indekslersiniz :) Ama o zaman her zaman uygulanmış bir DB kullanmak daha iyidir.
NSSet
ve ile ilgili olduğu için NSArray
cevabım doğru ve eksiksiz. Evet, başka veri yapıları oluşturabilirsiniz, ancak ben sadece bu ikisini karşılaştırıyorum.
NSArray
ve bazı işlevlere ihtiyacınız varsa NSSet
, doğru yanıt " NSArray
performansı kullanın ve feda edin" değildir. Cevap, ikisini birleştirmek veya farklı bir veri yapısı kullanmaktır.
Öğelere dizinlerine göre erişmek için bir dizi kullanılır. Herhangi bir öğe diziye birden çok kez eklenebilir. Diziler, öğelerinin sırasını korur.
Bir set, temelde yalnızca öğenin koleksiyonda olup olmadığını kontrol etmek için kullanılır. Öğelerin sıralama veya indeksleme kavramı yoktur. Bir sette iki kez öğe bulunduramazsınız.
Bir dizi bir eleman içerip içermediğini kontrol etmek isterse, tüm öğelerini kontrol etmelidir. Kümeler, daha hızlı algoritmalar kullanmak üzere tasarlanmıştır.
Değerleri olmayan bir sözlük gibi bir set hayal edebilirsiniz.
Dizi ve kümenin tek veri yapıları olmadığını unutmayın. Sıra, Yığın, Yığın, Fibonacci'nin Yığını gibi başka şeyler de vardır. Algoritmalar ve veri yapıları hakkında bir kitap okumanızı tavsiye ederim.
Daha fazla bilgi için wikipedia'ya bakın .
contains
operasyonu olduğunu O(n)
. Dizide bulunmadığında yapılan karşılaştırmaların sayısı n
. Nesne dizide olduğunda ortalama karşılaştırma sayısı 'dır n/2
. Nesne bulunsa bile, performans berbat.
NSArray
s'ye göre başka hız avantajları da vardır NSSet
. Her zaman olduğu gibi, bu bir değiş tokuş.
NSArray *Arr;
NSSet *Nset;
Arr=[NSArray arrayWithObjects:@"1",@"2",@"3",@"4",@"2",@"1", nil];
Nset=[NSSet setWithObjects:@"1",@"2",@"3",@"3",@"5",@"5", nil];
NSLog(@"%@",Arr);
NSLog(@"%@",Nset);
dizi
2015-12-04 11: 05: 40.935 [598: 15730] (1, 2, 3, 4, 2, 1)
set
2015-12-04 11: 05: 43.362 [598: 15730] {(3, 1, 2, 5)}
Ana farklılıklar zaten diğer cevaplarda verilmiştir.
Kümeler ve sözlüklerin uygulanma şekli nedeniyle (yani hash kullanımı), anahtarlar için değişken nesneler kullanılmamasına dikkat edilmesi gerektiğini belirtmek isterim.
Bir anahtar mutasyona uğratılırsa, karma (muhtemelen) de değişecek ve karma tablosunda farklı bir dizine / kova işaret edecektir. Orijinal değer silinmeyecek ve yapıyı numaralandırırken veya boyutu / sayısını sorarken aslında dikkate alınacaktır.
Bu, bazı hataların bulunmasının gerçekten zor olmasına yol açabilir.
İşte size bir güzel ayrıntılı karşılaştırmasını bulabilirsiniz NSArray
ve NSSet
veriyapılarıdır.
Kısa sonuçlar:
Evet, NSArray, yalnızca tutma ve yineleme açısından NSSet'ten daha hızlıdır. Oluşturma için% 50 kadar az ve yineleme için% 500 kadar daha hızlı. Ders: Yalnızca içeriği yinelemeniz gerekiyorsa, NSSet kullanmayın.
Elbette, dahil etme için test etmeniz gerekiyorsa, NSArray'den kaçınmak için çok çalışın. Hem yineleme hem de dahil etme testine ihtiyacınız olsa bile, muhtemelen yine de bir NSSet seçmelisiniz. Koleksiyonunuzu düzenli tutmanız ve ayrıca dahil edilmek için test etmeniz gerekiyorsa, her biri aynı nesneleri içeren iki koleksiyon (bir NSArray ve bir NSSet) tutmayı düşünmelisiniz.
NSDictionary, NSMapTable'dan daha yavaştır - çünkü anahtar verilerini kopyalamalıdır. Daha hızlı arama yaparak bunu telafi eder. Elbette ikisinin farklı yetenekleri var, bu yüzden çoğu zaman bu belirleme başka faktörler üzerinden yapılmalıdır.
Erişim hızı önemli olduğunda ve düzen önemli olmadığında veya başka yollarla belirlendiğinde (bir yüklem veya sıralama tanımlayıcısı aracılığıyla) tipik olarak bir Küme kullanırsınız . Örneğin Çekirdek Veriler, yönetilen nesnelere bir-çok ilişkisi aracılığıyla erişildiğinde kümeler kullanır
Sadece biraz eklemek için bazen sadece diziden kopyaları kaldırmak için kullanıyorum: -
NSMutableSet *set=[[NSMutableSet alloc]initWithArray:duplicateValueArray]; // will remove all the duplicate values