Saya mencoba untuk memahami mengapa Java ArrayDeque lebih baik daripada Java LinkedList karena keduanya mengimplementasikan antarmuka Deque.
Saya jarang melihat seseorang menggunakan ArrayDeque dalam kode mereka. Jika seseorang memberi lebih banyak penjelasan tentang bagaimana ArrayDeque diimplementasikan, itu akan sangat membantu.
Jika saya memahaminya, saya akan lebih percaya diri menggunakannya. Saya tidak dapat dengan jelas memahami implementasi JDK mengenai cara mengelola referensi kepala dan ekor.
java
deque
linked-list
arraydeque
Kejam
sumber
sumber
src.zip
. Ini adalah arsip dengan kode sumber kelas java. Saya sangat merekomendasikan untuk mempelajari struktur kelas ini dan internal untuk mendapatkan pemahaman yang lebih baik bagaimana cara kerja kelas java.Jawaban:
Struktur yang ditautkan mungkin merupakan struktur terburuk yang harus diulang dengan cache miss pada setiap elemen. Di atas itu mereka mengkonsumsi lebih banyak memori.
Jika Anda perlu menambah / menghapus kedua ujungnya, ArrayDeque secara signifikan lebih baik daripada daftar yang ditautkan. Akses acak setiap elemen juga O (1) untuk antrian siklik.
Satu-satunya operasi yang lebih baik dari daftar tertaut adalah menghapus elemen saat ini selama iterasi.
sumber
LinkedList
mengimplementasikanList
sementaraArrayDeque
tidak. Ini berarti bahwaLinkedList
memiliki metode sepertiindexOf
atauremove(int)
sementaraArrayDeque
belum. Terkadang itu penting.Saya percaya bahwa bottleneck kinerja utama
LinkedList
adalah kenyataan bahwa setiap kali Anda mendorong ke ujung deque, di balik layar implementasi mengalokasikan node daftar terkait baru, yang pada dasarnya melibatkan JVM / OS, dan itu mahal. Juga, setiap kali Anda muncul dari mana saja, node internalLinkedList
menjadi memenuhi syarat untuk pengumpulan sampah dan itu lebih banyak pekerjaan di belakang layar. Juga, karena node daftar tertaut dialokasikan di sana-sini, penggunaan cache CPU tidak akan memberikan banyak manfaat.Jika mungkin menarik, saya punya bukti yang menambahkan (menambahkan) elemen ke
ArrayList
atauArrayDeque
berjalan dalam waktu konstan diamortisasi; lihat ini .sumber
ArrayDeque
baru dengan Java 6, itulah sebabnya banyak kode (terutama proyek yang mencoba kompatibel dengan versi Java sebelumnya) tidak menggunakannya.Ini "lebih baik" dalam beberapa kasus karena Anda tidak mengalokasikan node untuk setiap item untuk dimasukkan; alih-alih semua elemen disimpan dalam array raksasa, yang diubah ukurannya jika sudah penuh.
sumber
Semua orang mengkritik
LinkedList
, pikirkan tentang setiap lelaki lain yang telah menggunakanList
di Jawa mungkin menggunakanArrayList
danLinkedList
sebagian besar waktu karena mereka telah sebelum Java 6 dan karena mereka yang diajarkan sebagai awal di sebagian besar buku.Tapi, itu tidak berarti, saya akan memihak
LinkedList
atau membabi butaArrayDeque
. Jika Anda ingin tahu, lihat benchmark di bawah ini yang dilakukan oleh Brian .Pengaturan pengujian mempertimbangkan:
Hasil tes:
Grafik:
Bawa pulang:
ArrayList
atauArrayDeque
dengan perkiraan kapasitas maksimum yang baik karena daftar tersebut mungkin diperlukan karena kendala memori yang ketat.LinkedList
tapak hati-hati ketika memutuskan untuk menggunakanArrayDeque
terutama karena TIDAK mengimplementasikanList
antarmuka (saya pikir itu alasannya cukup besar). Mungkin basis kode Anda berbicara ke antarmuka Daftar secara luas, kemungkinan besar dan Anda memutuskan untuk menggunakannyaArrayDeque
. Menggunakannya untuk implementasi internal mungkin ide yang bagus ...sumber
ArrayDeque dan LinkedList menerapkan antarmuka Deque tetapi implementasinya berbeda.
Perbedaan utama:
Kelas ArrayDeque adalah implementasi array resizable dari antarmuka Deque dan kelas LinkedList adalah implementasi daftar
Elemen NULL dapat ditambahkan ke LinkedList tetapi tidak di ArrayDeque
ArrayDeque lebih efisien daripada LinkedList untuk menambah dan menghapus operasi di kedua ujungnya dan implementasi LinkedList efisien untuk menghilangkan elemen saat ini selama iterasi
The LinkedList pelaksanaan mengkonsumsi memori lebih dari ArrayDeque
Jadi, jika Anda tidak harus mendukung elemen NULL && mencari lebih sedikit memori & & efisiensi menambah / menghapus elemen di kedua ujungnya, ArrayDeque adalah yang terbaik
Lihat dokumentasi untuk lebih jelasnya.
sumber
header.previous.element
). Klaim "efisiensi memori" juga dapat ditantang karena array backing selalu diubah ukurannya menjadi kekuatan berikutnya dari 2.Iterator
untuk mengakses elemen terakhir, operasinya adalah O (N) untuk kedua kelas. Saat Anda menggunakanDeque
antarmuka umum , mengakses elemen terakhir adalah O (1) untuk kedua kelas. Terlepas dari sudut pandang mana Anda mengambil, menghubungkan O (1) keArrayDeque
dan O (N)LinkedList
pada saat yang sama, salah.walaupun
ArrayDeque<E>
danLinkedList<E>
keduanya telah mengimplementasikanDeque<E>
Interface, tetapi ArrayDeque pada dasarnya menggunakan array ObjectE[]
untuk menjaga elemen-elemen di dalam Object-nya, sehingga umumnya menggunakan indeks untuk menemukan elemen head dan tail.Singkatnya, ini hanya berfungsi seperti Deque (dengan semua metode Deque), namun menggunakan struktur data array. Mengenai mana yang lebih baik, tergantung pada bagaimana dan di mana Anda menggunakannya.
sumber
Itu tidak selalu terjadi.
Misalnya, dalam kasus di bawah ini
linkedlist
memiliki kinerja yang lebih baik daripadaArrayDeque
sesuai dengan leetcode 103.sumber
Kompleksitas waktu untuk ArrayDeque untuk mengakses elemen adalah O (1) dan untuk LinkList adalah O (N) untuk mengakses elemen terakhir. ArrayDeque bukan thread aman sehingga sinkronisasi secara manual diperlukan sehingga Anda dapat mengaksesnya melalui beberapa utas dan sehingga lebih cepat.
sumber
LinkedList
pada JavaCollection
, itu terhubung dua kali lipat dan memiliki akses cepat ke kepala dan ekor, sehingga akses ke elemen terakhir juga membutuhkan O (1).