Apa perbedaan antara ArrayList
dan List<>
di C #?
Apakah hanya yang List<>
memiliki tipe sementara ArrayList
tidak?
List<>
secara umum, sementara yang itu bertanya List<object>
secara spesifik
Apa perbedaan antara ArrayList
dan List<>
di C #?
Apakah hanya yang List<>
memiliki tipe sementara ArrayList
tidak?
List<>
secara umum, sementara yang itu bertanya List<object>
secara spesifik
Jawaban:
Ya, cukup banyak. List<T>
adalah kelas generik. Ini mendukung menyimpan nilai-nilai dari jenis tertentu tanpa casting ke atau dari object
(yang akan menyebabkan tinju / unboxing overhead ketika T
merupakan tipe nilai dalam ArrayList
case). ArrayList
hanya menyimpan object
referensi. Sebagai kumpulan generik, List<T>
mengimplementasikan IEnumerable<T>
antarmuka generik dan dapat digunakan dengan mudah di LINQ (tanpa memerlukan apa pun Cast
atau OfType
panggilan).
ArrayList
milik hari-hari dimana C # tidak memiliki obat generik. Sudah usang mendukung List<T>
. Anda tidak boleh menggunakan ArrayList
kode baru yang menargetkan .NET> = 2.0 kecuali Anda harus berinteraksi dengan API lama yang menggunakannya.
ArrayList
saat runtime. Namun secara statis, itu akan membutuhkan para pemain ArrayList
.
Menggunakan List<T>
Anda dapat mencegah kesalahan casting. Sangat berguna untuk menghindari kesalahan casting runtime .
Contoh:
Di sini (menggunakan ArrayList
) Anda dapat mengkompilasi kode ini tetapi Anda akan melihat kesalahan eksekusi nanti.
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
}
Jika Anda menggunakan List
, Anda menghindari kesalahan ini:
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;
}
Referensi: MSDN
Untuk menambah poin di atas. Menggunakan ArrayList
sistem operasi 64bit membutuhkan memori 2x daripada menggunakan sistem operasi 32bit. Sementara itu, daftar generik List<T>
akan menggunakan banyak memori rendah daripada ArrayList
.
misalnya jika kita menggunakan ArrayList
19MB dalam 32-bit, itu akan membutuhkan 39MB dalam 64-bit. Tetapi jika Anda memiliki daftar generik List<int>
8MB dalam 32-bit, ia hanya membutuhkan 8.1MB dalam 64-bit, yang merupakan perbedaan 481% jika dibandingkan dengan ArrayList.
Sumber: ArrayList vs. generik untuk tipe primitif dan 64-bit
Perbedaan lain yang ditambahkan adalah sehubungan dengan Sinkronisasi Utas.
ArrayList
menyediakan beberapa keamanan thread melalui properti Synchronized, yang mengembalikan pembungkus aman thread di sekitar koleksi. Pembungkus bekerja dengan mengunci seluruh koleksi pada setiap operasi tambah atau hapus. Oleh karena itu, setiap utas yang mencoba mengakses koleksi harus menunggu gilirannya mengambil satu kunci. Ini tidak dapat diskalakan dan dapat menyebabkan penurunan kinerja yang signifikan untuk koleksi besar.
List<T>
tidak menyediakan sinkronisasi utas apa pun; kode pengguna harus memberikan semua sinkronisasi ketika item ditambahkan atau dihapus pada banyak utas secara bersamaan.
Info lebih lanjut di sini Utas Sinkronisasi di Framework .Net
ArrayList
jika itu bisa dihindari, tetapi ini adalah alasan yang konyol. Bagaimanapun, bungkusnya sepenuhnya opsional; jika Anda tidak perlu mengunci atau jika Anda membutuhkan lebih banyak kontrol granular, jangan gunakan pembungkus.
Jawaban sederhana adalah,
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
Silakan baca dokumen resmi Microsoft : https://blogs.msdn.microsoft.com/kcwalina/2005/09/23/system-collections-vs-system-collection-generic-and-system-collections-objectmodel/
Catatan : Anda harus tahu Generik sebelum memahami perbedaannya: https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/generics/
ArrayList
adalah koleksi dari berbagai jenis data sedangkan List<>
koleksi dari jenis yang sama dari depedencties sendiri.
ArrayList
bukan tipe aman sedangkan List<T>
tipe aman. Sederhana :).
Kinerja telah disebutkan dalam beberapa jawaban sebagai faktor pembeda, tetapi untuk mengatasi " Berapa banyak lebih lambat ArrayList
? "Dan" Mengapa lebih lambat secara keseluruhan?”, Lihat di bawah.
Kapan pun tipe nilai digunakan sebagai elemen, kinerja akan turun secara dramatis ArrayList
. Pertimbangkan kasus penambahan elemen. Karena tinju terjadi - karena ArrayList
Tambah hanya membutuhkan object
parameter - Pengumpul Sampah akan terpicu untuk melakukan lebih banyak pekerjaan daripada dengan List<T>
.
Berapa perbedaan waktu? Setidaknya beberapa kali lebih lambat dibandingkan dengan List<T>
. Lihatlah apa yang terjadi dengan kode yang menambahkan nilai 10 mil int ke ArrayList
vs List<T>
:
Itu perbedaan waktu lari 5x di kolom 'Mean', disorot dengan warna kuning. Perhatikan juga perbedaan dalam jumlah pengumpulan sampah yang dilakukan untuk masing-masing, disorot dalam warna merah (tidak ada GC / 1000 berjalan).
Menggunakan profiler untuk melihat apa yang terjadi dengan cepat menunjukkan bahwa sebagian besar waktu dihabiskan untuk melakukan GCs , bukan benar-benar menambahkan elemen. Bilah coklat di bawah mewakili aktivitas Pemblokir Sampah yang menghalangi:
Saya telah menulis analisis terperinci tentang apa yang terjadi dengan ArrayList
skenario di atas di sini https://mihai-albert.com/2019/12/15/boxing-performance-in-c-analysis-and-benchmark/ .
Temuan serupa ada di “CLR via C #” oleh Jeffrey Richter. Dari bab 12 (Generik):
[…] Ketika saya mengkompilasi dan menjalankan rilis build (dengan optimisasi dihidupkan) dari program ini di komputer saya, saya mendapatkan output berikut.
00:00: 01.6246959 (GCs = 6) Daftar <Int32>
00: 00: 10.8555008 (GCs = 390) ArrayDaftar Int32
00: 00: 02.5427847 (GCs = 4) Daftar <String>
00: 00: 02.7944831 (GCs = 7 ) ArrayList of StringOutput di sini menunjukkan bahwa menggunakan algoritma Daftar generik dengan tipe Int32 jauh lebih cepat daripada menggunakan algoritma ArrayList non-generik dengan Int32. Faktanya, perbedaannya sangat fenomenal: 1,6 detik versus hampir 11 detik. Itu ~ 7 kali lebih cepat ! Selain itu, menggunakan tipe nilai (Int32) dengan ArrayList menyebabkan banyak operasi tinju terjadi, yang menghasilkan 390 pengumpulan sampah. Sementara itu, algoritma Daftar membutuhkan 6 koleksi sampah.
Saya pikir, perbedaan antara ArrayList
dan List<T>
adalah:
List<T>
, di mana T adalah tipe-nilai lebih cepat dari ArrayList
. Ini karena List<T>
menghindari tinju / unboxing (di mana T adalah tipe-nilai).ArrayList
digunakan hanya untuk kompatibilitas mundur. (bukan perbedaan nyata, tapi saya pikir ini adalah catatan penting).ArrayList
kemudianList<T>
ArrayList
memiliki IsSynchronized
properti. Jadi, mudah untuk membuat dan menggunakan sinkronisasi ArrayList
. Saya tidak menemukan IsSynchronized
properti untuk List<T>
. Perlu diingat juga bahwa jenis sinkronisasi ini relatif tidak efisien, 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
memiliki ArrayList.SyncRoot
properti yang dapat digunakan untuk sinkronisasi ( msdn ). List<T>
belum memiliki SyncRoot
properti, jadi dalam konstruksi berikut Anda perlu menggunakan beberapa objek jika Anda menggunakan List<T>
:
ArrayList myCollection = new ArrayList();
lock(myCollection.SyncRoot) // ofcourse you can use another object for this goal
{
foreach (object item in myCollection)
{
// ...
}
}
Seperti disebutkan dalam dokumentasi .NET Framework
Kami tidak menyarankan Anda menggunakan
ArrayList
kelas untuk pengembangan baru. Sebagai gantinya, kami menyarankan Anda menggunakanList<T>
kelas generik . TheArrayList
kelas dirancang untuk menahan koleksi heterogen benda. Namun, itu tidak selalu menawarkan kinerja terbaik. Sebagai gantinya, kami merekomendasikan yang berikut:
- Untuk koleksi objek yang heterogen, gunakan tipe
List<Object>
(dalam C #) atauList(Of Object)
(dalam Visual Basic).- Untuk koleksi objek yang homogen, gunakan
List<T>
kelas.
Lihat juga koleksi non-generik tidak boleh digunakan
Menggunakan "Daftar" Anda dapat mencegah kesalahan casting. Sangat berguna untuk menghindari kesalahan casting runtime.
Contoh:
Di sini (menggunakan ArrayList) Anda dapat mengkompilasi kode ini tetapi Anda akan melihat kesalahan eksekusi nanti.
// 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.
}
}
Bagi saya ini semua tentang mengetahui data Anda. Jika saya terus memperluas kode saya berdasarkan efisiensi, saya harus memilih opsi Daftar sebagai cara menguraikan data saya tanpa langkah selalu perlu bertanya-tanya tentang jenis, terutama 'Jenis Kustom'. Jika mesin memahami perbedaan dan dapat menentukan pada itu pada jenis data apa saya benar-benar berurusan dengan lalu mengapa saya harus menghalangi dan membuang waktu melalui perputaran penentuan 'JIKA KEMUDIAN LAIN'? Filosofi saya adalah membiarkan mesin bekerja untuk saya alih-alih saya mengerjakan mesin? Mengetahui perbedaan unik dari berbagai perintah kode objek berjalan jauh dalam membuat kode Anda efisien.
Tom Johnson (Satu Entri ... Satu Pintu Keluar)