Katakanlah Anda perlu memiliki daftar / array bilangan bulat yang sering Anda perlukan, dan maksud saya sangat sering. Alasannya mungkin berbeda-beda, tetapi katakanlah itu berada di jantung lingkaran paling dalam dari pemrosesan volume tinggi.
Secara umum, orang akan memilih untuk menggunakan Daftar (Daftar) karena fleksibilitas ukurannya. Selain itu, dokumentasi msdn mengklaim Daftar menggunakan array secara internal dan harus bekerja sama cepatnya (tampilan cepat dengan Reflector mengonfirmasi hal ini). Namun demikian, ada beberapa overhead yang terlibat.
Apakah ada yang benar-benar mengukur ini? akan mengulangi 6M kali melalui daftar akan sama dengan array?
T[]
vs.List<T>
dapat membuat perbedaan kinerja yang besar. Saya baru saja mengoptimalkan aplikasi intensif yang sangat (bersarang) untuk berpindah dari daftar ke array di .NET 4.0. Saya mengharapkan peningkatan 5% hingga 10% tetapi mendapatkan lebih dari 40% peningkatan! Tidak ada perubahan lain selain pindah langsung dari daftar ke array. Semua enumerasi dilakukan denganforeach
pernyataan. Berdasarkan jawaban Marc Gravell, sepertinyaforeach
denganList<T>
sangat buruk.Jawaban:
Sangat mudah diukur ...
Dalam sejumlah kecil kode pemrosesan loop ketat di mana saya tahu panjangnya diperbaiki, saya menggunakan array untuk sedikit tambahan mikro-optimasi; array bisa sedikit lebih cepat jika Anda menggunakan pengindeks / untuk formulir - tetapi IIRC percaya itu tergantung pada jenis data dalam array. Tetapi kecuali Anda perlu mengoptimalkan mikro, tetap sederhana dan gunakan
List<T>
dll.Tentu saja, ini hanya berlaku jika Anda membaca semua data; kamus akan lebih cepat untuk pencarian berbasis kunci.
Inilah hasil saya menggunakan "int" (angka kedua adalah sebuah checksum untuk memverifikasi mereka semua melakukan pekerjaan yang sama):
(diedit untuk memperbaiki bug)
berdasarkan rig uji:
sumber
Ringkasan:
Array perlu digunakan:
Daftar harus digunakan:
LinkedList perlu menggunakan:
Jika perlu menambahkan sel di awal / tengah / akhir daftar (sering)
Jika diperlukan hanya akses sekuensial (maju / mundur)
Jika Anda perlu menyimpan item BESAR, tetapi jumlah item rendah.
Lebih baik tidak menggunakan item dalam jumlah besar, karena menggunakan memori tambahan untuk tautan.
Keterangan lebih lanjut:
Lebih banyak detail:
https://stackoverflow.com/a/29263914/4423545
sumber
Saya pikir kinerjanya akan sangat mirip. Overhead yang terlibat saat menggunakan Daftar vs Array adalah, IMHO ketika Anda menambahkan item ke daftar, dan ketika daftar harus meningkatkan ukuran array yang digunakan secara internal, ketika kapasitas array tercapai.
Misalkan Anda memiliki Daftar dengan Kapasitas 10, maka Daftar akan meningkatkan kapasitasnya setelah Anda ingin menambahkan elemen ke-11. Anda dapat mengurangi dampak kinerja dengan menginisialisasi Kapasitas daftar ke jumlah item yang akan dipegang.
Tetapi, untuk mencari tahu apakah iterasi pada Daftar adalah secepat iterasi pada array, mengapa Anda tidak membandingkannya?
Di sistem saya; iterating melalui array mengambil 33msec; iterating atas daftar butuh 66msec.
Sejujurnya, saya tidak berharap bahwa variasinya akan sebesar itu. Jadi, saya telah menempatkan iterasi saya dalam satu lingkaran: sekarang, saya menjalankan iterasi 1000 kali. Hasilnya adalah:
Sekarang, variasinya tidak terlalu besar lagi, tetapi masih ...
Oleh karena itu, saya telah memulai .NET Reflector, dan pengambil indekser dari kelas Daftar, terlihat seperti ini:
Seperti yang Anda lihat, ketika Anda menggunakan pengindeks Daftar, Daftar melakukan pemeriksaan apakah Anda tidak akan keluar dari batas array internal. Pemeriksaan tambahan ini disertai dengan biaya.
sumber
jika Anda hanya mendapatkan nilai tunggal dari salah satu (tidak dalam satu lingkaran) maka keduanya melakukan pengecekan batas (Anda berada dalam kode yang dikelola ingat) itu hanya daftar melakukannya dua kali. Lihat catatannya nanti untuk mengapa ini mungkin bukan masalah besar.
Jika Anda menggunakan milik Anda untuk (int int = 0; i <x. [Panjang / Hitung]; i ++) maka perbedaan utama adalah sebagai berikut:
Jika Anda menggunakan foreach maka perbedaan utama adalah sebagai berikut:
Pengecekan batas seringkali bukan masalah besar (terutama jika Anda menggunakan CPU dengan prediksi mendalam tentang pipa dan cabang - norma untuk sebagian besar hari ini) tetapi hanya profil Anda sendiri yang dapat memberi tahu Anda jika itu merupakan masalah. Jika Anda berada di bagian kode Anda di mana Anda menghindari alokasi tumpukan (contoh yang baik adalah perpustakaan atau dalam implementasi kode hash) maka memastikan variabel diketik sebagai Daftar tidak IList akan menghindari perangkap itu. Seperti biasa profil jika itu penting.
sumber
[ Lihat juga pertanyaan ini ]
Saya telah memodifikasi jawaban Marc untuk menggunakan angka acak aktual dan benar-benar melakukan pekerjaan yang sama dalam semua kasus.
Hasil:
Disusun sebagai Rilis di bawah VS 2008 SP1. Berjalan tanpa debugging pada [email protected], .NET 3.5 SP1.
Kode:
sumber
Pengukurannya bagus, tetapi Anda akan mendapatkan hasil yang sangat berbeda tergantung pada apa yang Anda lakukan persis di lingkaran dalam Anda. Ukur situasi Anda sendiri. Jika Anda menggunakan multi-threading, itu saja adalah aktivitas non-sepele.
sumber
Memang, jika Anda melakukan beberapa perhitungan kompleks di dalam loop, maka kinerja pengindeks array versus pengindeks daftar mungkin sangat kecil, yang pada akhirnya, itu tidak masalah.
sumber
Inilah yang menggunakan Kamus, IEnumerable:
sumber
Jangan mencoba menambah kapasitas dengan menambah jumlah elemen.
Performa
sumber
Saya khawatir bahwa tolok ukur yang diposting di jawaban lain masih akan meninggalkan ruang bagi kompiler untuk mengoptimalkan, menghilangkan atau menggabungkan loop jadi saya menulis satu yang:
Hasilnya, array langsung memiliki kinerja sekitar 250% lebih baik daripada akses ke array yang dibungkus dengan IList:
Berikut kodenya:
sumber
Karena Daftar <> menggunakan array secara internal, kinerja dasar harus sama. Dua alasan, mengapa Daftar mungkin sedikit lebih lambat:
Untuk memeriksa apakah ada bedanya untuk Anda, mungkin lebih baik sesuaikan fungsi waktu yang diposkan ke daftar ukuran yang Anda rencanakan untuk digunakan dan lihat bagaimana hasilnya untuk kasing khusus Anda.
sumber
Karena saya memiliki pertanyaan serupa, ini membuat saya memulai dengan cepat.
Pertanyaan saya sedikit lebih spesifik, 'apa metode tercepat untuk implementasi array refleksif'
Pengujian yang dilakukan oleh Marc Gravell menunjukkan banyak, tetapi tidak tepat waktu akses. Waktunya termasuk perulangan di array dan daftar juga. Karena saya juga menemukan metode ketiga yang ingin saya uji, 'Kamus', hanya untuk membandingkan, saya menambah kode tes hist.
Pertama, saya melakukan tes menggunakan konstanta, yang memberi saya waktu tertentu termasuk loop. Ini adalah waktu yang 'telanjang', tidak termasuk akses yang sebenarnya. Kemudian saya melakukan tes dengan mengakses struktur subjek, ini memberi saya dan waktu, termasuk perulangan dan akses aktual.
Perbedaan antara timing 'bare' dan timing 'overhead induced' memberi saya indikasi waktu 'struktur akses'.
Tetapi seberapa akurat waktu ini? Selama pengujian windows akan melakukan beberapa waktu mengiris untuk shure. Saya tidak punya informasi tentang waktu mengiris tetapi saya berasumsi itu didistribusikan secara merata selama pengujian dan dalam urutan puluhan msec yang berarti bahwa ketepatan waktu harus dalam urutan +/- 100 msec atau lebih. Perkiraan yang agak kasar? Pokoknya sumber kesalahan mearure sistematis.
Juga, tes dilakukan dalam mode 'Debug' tanpa optimalisasi. Kalau tidak, kompiler dapat mengubah kode tes yang sebenarnya.
Jadi, saya mendapatkan dua hasil, satu untuk konstanta, bertanda '(c)', dan satu untuk akses ditandai '(n)' dan perbedaannya 'dt' memberi tahu saya berapa banyak waktu yang dibutuhkan akses aktual.
Dan ini hasilnya:
Dengan perkiraan yang lebih baik pada kesalahan waktu (bagaimana menghapus kesalahan pengukuran sistematis karena waktu mengiris?) Lebih banyak yang bisa dikatakan tentang hasilnya.
Sepertinya List / foreach memiliki akses tercepat tetapi overhead membunuhnya.
Perbedaan antara Daftar / untuk dan Daftar / foreach adalah stange. Mungkin ada uang tunai yang terlibat?
Lebih lanjut, untuk akses ke array tidak masalah jika Anda menggunakan
for
loop atauforeach
loop. Hasil waktu dan keakuratannya membuat hasil 'kompatibel'.Menggunakan kamus adalah yang paling lambat, saya hanya mempertimbangkannya karena di sisi kiri (pengindeks) saya memiliki daftar integer yang jarang dan bukan rentang seperti yang digunakan dalam tes ini.
Berikut adalah kode tes yang dimodifikasi.
sumber
Dalam beberapa tes singkat saya menemukan kombinasi keduanya lebih baik dalam apa yang saya sebut Matematika intensif:
Tipe:
List<double[]>
Tipe:
List<List<double>>
Tipe:
double[rows * columns]
Menjalankan Kode:
Saya berharap kami memiliki beberapa Kelas Matriks Akselerasi Hardware Terkemuka seperti yang dilakukan oleh Tim NET dengan
System.Numerics.Vectors
Kelas!C # bisa menjadi Bahasa ML terbaik dengan sedikit lebih banyak pekerjaan di bidang ini!
sumber