Arasındaki fark nedir ArrayList
ve List<>
C #?
Sadece List<>
bir türü ArrayList
var değil mi?
List<>
genel olarak soruyor , bu da List<object>
özellikle soruyor
Arasındaki fark nedir ArrayList
ve List<>
C #?
Sadece List<>
bir türü ArrayList
var değil mi?
List<>
genel olarak soruyor , bu da List<object>
özellikle soruyor
Yanıtlar:
Evet, hemen hemen. List<T>
genel bir sınıftır. Belirli bir tipteki değerlerin döküm yapılmadan veya gönderilmeden depolanmasını destekler object
(bu T
, ArrayList
durumda bir değer türü olduğunda boks / kutudan çıkarma yüküne neden olur ). ArrayList
basitçe object
referansları saklar . Genel bir koleksiyon olarak, List<T>
genel IEnumerable<T>
arayüzü uygular ve LINQ'da (herhangi bir çağrı Cast
veya OfType
çağrı gerektirmeden ) kolayca kullanılabilir .
ArrayList
C # 'ın jenerik içermediği günlere aittir. Lehine reddedildi List<T>
. Bunu ArrayList
kullanan eski bir API ile arayüz kurmak zorunda kalmadıkça .NET> = 2.0'ı hedefleyen yeni kodlarda kullanmamalısınız.
ArrayList
çalışma zamanında etkin olarak aynıdır . Statik olarak, bununla birlikte bir oyuncu kadrosu gerekir ArrayList
.
Kullanarak List<T>
döküm hatalarını önleyebilirsiniz. Bir çalışma zamanı döküm hatasını önlemek için çok kullanışlıdır .
Misal:
Burada (kullanarak ArrayList
) bu kodu derleyebilirsiniz, ancak daha sonra bir yürütme hatası göreceksiniz.
ArrayList array1 = new ArrayList();
array1.Add(1);
array1.Add("Pony"); //No error at compile process
int total = 0;
foreach (int num in array1)
{
total += num; //-->Runtime Error
}
Kullanırsanız List
, şu hatalardan kaçınırsınız:
List<int> list1 = new List<int>();
list1.Add(1);
//list1.Add("Pony"); //<-- Error at compile process
int total = 0;
foreach (int num in list1 )
{
total += num;
}
Referans: MSDN
Yukarıdaki noktalara eklemek için. Kullanılması ArrayList
64bit işletim sisteminde 32 bit işletim sisteminde kullanmak yerine 2x bellek alır. Bu arada, genel liste List<T>
çok daha az bellek kullanır ArrayList
.
örneğin ArrayList
, 32 bit'te 19 MB'lık bir a kullanırsak 64 bit'te 39 MB gerekir. Ancak List<int>
32-bit'de 8MB'lık genel bir listeniz varsa , 64-bit'de sadece 8.1MB alır, bu da ArrayList ile karşılaştırıldığında% 481'lik bir farktır.
Kaynak: İlkel türler ve 64 bit için ArrayList'in genel Listesi
Eklenecek bir diğer fark, Konu Senkronizasyonu ile ilgilidir.
ArrayList
, koleksiyonun çevresinde bir iş parçacığı için güvenli sarmalayıcı döndüren Synchronized özelliği aracılığıyla iş parçacığı güvenliği sağlar. Sargı, toplama veya çıkarma işlemlerinin tümünde tüm koleksiyonu kilitleyerek çalışır. Bu nedenle, koleksiyona erişmeye çalışan her iş parçacığı sırayla bir kilit almak için beklemek gerekir. Bu ölçeklenebilir değildir ve büyük koleksiyonlar için önemli performans düşüşüne neden olabilir.
List<T>
herhangi bir evre senkronizasyonu sağlamaz; eşzamanlı olarak birden çok iş parçacığına öğe eklendiğinde veya kaldırıldığında kullanıcı kodu tüm eşitlemeyi sağlamalıdır.
Daha fazla bilgi için .Net Framework'te Konu Senkronizasyonu
ArrayList
, ama bu aptalca bir sebep. Sonuçta sargı tamamen isteğe bağlıdır; Kilitlemeye ihtiyacınız yoksa veya daha ayrıntılı bir denetime ihtiyacınız varsa, ambalajı kullanmayın.
Basit Yanıt,
ArrayList arrayList = new ArrayList();
List<int> list = new List<int>();
arrayList.Add(1);
arrayList.Add("String");
arrayList.Add(new object());
list.Add(1);
list.Add("String"); // Compile-time Error
list.Add(new object()); // Compile-time Error
Lütfen Microsoft resmi belgesini okuyun : https://blogs.msdn.microsoft.com/kcwalina/2005/09/23/system-collections-vs-system-collection-generic-and-system-collections-objectmodel/
Not : Farkı anlamadan önce Generics'i bilmelisiniz: https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/generics/
ArrayList
farklı türdeki verilerin toplanmasıdır, oysa List<>
kendi bağımlılıklarının benzer türlerinin toplanmasıdır.
ArrayList
güvenli değil List<T>
, güvenli. Basit :).
Performans birkaç cevapta farklılaştırıcı bir faktör olarak belirtilmiştir, ancak “ Ne kadar yavaştır ArrayList
? ”Ve“ Genel olarak neden daha yavaş? ”, Aşağıya bakın.
Değer türleri öğe olarak kullanıldığında, performans önemli ölçüde düşer ArrayList
. Yalnızca öğe ekleme konusunu düşünün. Boks devam ettiği için - ArrayList
's Add sadece object
parametre alır gibi - Çöp Toplayıcı olduğundan çok daha fazla iş yapmak için tetiklenir List<T>
.
Zaman farkı ne kadar? En az birkaç kat daha yavaş List<T>
. Sadece kod 10 mil int değerler ekleyerek ile ne bir göz atın ArrayList
vs List<T>
:
Bu , Sarı ile vurgulanan 'Ortalama' sütununda 5x'lik bir çalışma süresi farkıdır . Ayrıca, her biri için kırmızı renkle vurgulanmış (GC / 1000 çalıştırma sayısı) yapılan çöp toplama sayısındaki farka dikkat edin.
Neler olup bittiğini hızlı bir şekilde görmek için bir profil oluşturucu kullanmak, çoğu zaman aslında öğe eklemenin aksine GC'leri harcadığını gösterir . Aşağıdaki kahverengi çubuklar Çöp Toplayıcı etkinliğinin engellenmesini temsil eder:
Yukarıdaki ArrayList
senaryoda neler olup bittiğinin ayrıntılı bir analizini burada yazdım https://mihai-albert.com/2019/12/15/boxing-performance-in-c-analysis-and-benchmark/ .
Benzer bulgular Jeffrey Richter'in “C # üzerinden CLR” de. Bölüm 12'den (Jenerikler):
[…] Derleme ve bilgisayarımda bu programın bir sürüm derleme (optimizasyon açıkken) çalıştırdığınızda, aşağıdaki çıktıyı alıyorum.
00: 00: 01.6246959 (KR = 6) Liste <Int32>
00: 00: 10,8555008 (KR = 390) ArrayList Int32
00: 00: 02.5427847 (KR = 4) listesi <String>
00: 00: 02.7944831 (KR = 7 ) Dizi DizisiBuradaki çıktı, Int32 türüyle genel Liste algoritmasının kullanılmasının, genel olmayan ArrayList algoritmasını Int32 ile kullanmaktan çok daha hızlı olduğunu göstermektedir. Aslında, fark olağanüstü: 1,6 saniye ve neredeyse 11 saniye. Bu ~ 7 kat daha hızlı ! Buna ek olarak, ArrayList ile bir değer türü (Int32) kullanmak, çok fazla boks işleminin oluşmasına neden olur ve bu da 390 çöp toplama ile sonuçlanır. Bu arada, Liste algoritması 6 çöp toplama gerektiriyordu.
Ben arasındaki farklar, düşünmek ArrayList
ve List<T>
şunlardır:
List<T>
, burada T değer türünden daha hızlıdır ArrayList
. Bunun nedeni List<T>
, boks / kutudan kaçınmaktır (burada T değer tipidir).ArrayList
sadece geriye dönük uyumluluk için kullanılır. (gerçek bir fark değil, ama önemli bir not olduğunu düşünüyorum).ArrayList
o zaman daha kolaydırList<T>
ArrayList
sahiptir IsSynchronized
özelliğini. Bu nedenle, senkronize edilmiş oluşturmak ve kullanmak kolaydır ArrayList
. İçin IsSynchronized
mülk bulamadım List<T>
. Ayrıca bu tür senkronizasyonun göreceli olarak yetersiz olduğunu unutmayın, msdn ):
var arraylist = new ArrayList();
var arrayListSyncronized = ArrayList.Synchronized(arraylist
Console.WriteLine($"syncronized {arraylist.IsSynchronized}");
Console.WriteLine($"syncronized {arrayListSyncronized.IsSynchronized}");
var list = new List<object>();
var listSyncronized = ArrayList.Synchronized(list);
Console.WriteLine($"syncronized {list.IsSynchronized}");//error, no such prop
Console.WriteLine($"syncronized {list.IsSynchronized}");//error, no such prop
ArrayList
yer alır ArrayList.SyncRoot
syncronisation (kullanılabilir özelliği msdn ). List<T>
sahip değil SyncRoot
mülkiyet, böylece aşağıdaki yapımında kullandığınız takdirde bazı nesne kullanmak gerekmez List<T>
:
ArrayList myCollection = new ArrayList();
lock(myCollection.SyncRoot) // ofcourse you can use another object for this goal
{
foreach (object item in myCollection)
{
// ...
}
}
.NET Framework belgelerinde belirtildiği gibi
ArrayList
Yeni geliştirme için sınıfı kullanmanızı önermiyoruz . Bunun yerine, genelList<T>
sınıfı kullanmanızı öneririz .ArrayList
Sınıf nesnelerinin heterojen koleksiyonları tutmak için tasarlanmıştır. Ancak, her zaman en iyi performansı sunmaz. Bunun yerine, aşağıdakileri öneririz:
- Heterojen bir nesne koleksiyonu için,
List<Object>
(C #) veyaList(Of Object)
(Visual Basic) türünü kullanın.- Homojen bir nesne koleksiyonu için
List<T>
sınıfı kullanın .
Ayrıca bkz. Jenerik olmayan koleksiyonlar kullanılmamalıdır
"Liste" kullanarak döküm hatalarını önleyebilirsiniz. Bir çalışma zamanı döküm hatasını önlemek için çok kullanışlıdır.
Misal:
Burada (ArrayList kullanarak) bu kodu derleyebilirsiniz, ancak daha sonra bir yürütme hatası görürsünüz.
// Create a new ArrayList
System.Collections.ArrayList mixedList = new System.Collections.ArrayList();
// Add some numbers to the list
mixedList.Add(7);
mixedList.Add(21);
// Add some strings to the list
mixedList.Add("Hello");
mixedList.Add("This is going to be a problem");
System.Collections.ArrayList intList = new System.Collections.ArrayList();
System.Collections.ArrayList strList = new System.Collections.ArrayList();
foreach (object obj in mixedList)
{
if (obj.GetType().Equals(typeof(int)))
{
intList.Add(obj);
}
else if (obj.GetType().Equals(typeof(string)))
{
strList.Add(obj);
}
else
{
// error.
}
}
Benim için her şey verilerinizi bilmekle ilgili. Kodumu verimlilik temelinde genişletmeye devam edersem, her zaman türleri, özellikle de 'Özel Türleri' merak etmenin gereksiz adımı olmadan verilerimin deşifre edilmesi için Liste seçeneğini seçmeliyim. Makine farkı anlar ve aslında ne tür verilerle uğraştığımı belirleyebiliyorsa, neden 'BAŞKA EĞER İSE' tespitlerinin dönmeleriyle neden yol alıp zaman harcamalıyım? Felsefem, makine üzerinde çalışmak yerine makinenin benim için çalışmasına izin vermektir. Farklı nesne kodu komutlarının benzersiz farklılıklarını bilmek, kodunuzu verimli hale getirmenin uzun bir yoludur.
Tom Johnson (Bir Giriş ... Bir Çıkış)