Sejak
- keduanya adalah wadah memori yang berdekatan;
- Dari segi fitur, deque memiliki hampir semua yang dimiliki vektor tetapi lebih, karena lebih efisien untuk dimasukkan di depan.
Mengapa whould orang lebih memilih std::vector
untuk std::deque
?
Sejak
Mengapa whould orang lebih memilih std::vector
untuk std::deque
?
Jawaban:
Elemen dalam deque
yang tidak bersebelahan di memori; vector
elemen dijamin. Jadi, jika Anda perlu berinteraksi dengan pustaka C biasa yang membutuhkan larik yang berdekatan, atau jika Anda peduli (sangat) tentang lokalitas spasial, Anda mungkin lebih suka vector
. Selain itu, karena ada beberapa pembukuan tambahan, operasi lain mungkin (sedikit) lebih mahal daripada vector
operasi yang setara . Di sisi lain, menggunakan banyak / contoh besar dari vector
dapat menyebabkan fragmentasi heap yang tidak perlu (memperlambat panggilan kenew
).
Juga, seperti yang ditunjukkan di tempat lain di StackOverflow , ada lebih banyak diskusi bagus di sini: http://www.gotw.ca/gotw/054.htm .
Untuk mengetahui perbedaannya, seseorang harus mengetahui bagaimana deque
penerapannya secara umum. Memori dialokasikan dalam blok dengan ukuran yang sama, dan mereka dirangkai bersama (sebagai array atau mungkin vektor).
Jadi untuk menemukan elemen ke-n, Anda menemukan blok yang sesuai kemudian mengakses elemen di dalamnya. Ini adalah waktu yang konstan, karena selalu persis 2 pencarian, tetapi itu masih lebih banyak daripada vektor.
vector
juga berfungsi dengan baik dengan API yang menginginkan buffer berdekatan karena keduanya merupakan C API atau lebih fleksibel dalam mengambil pointer dan panjang. (Dengan demikian Anda dapat memiliki vektor di bawah atau array biasa dan memanggil API dari blok memori Anda).
Dimana deque
keuntungan terbesarnya adalah:
Yang kedua kurang dikenal, tetapi untuk ukuran koleksi yang sangat besar:
Ketika saya berurusan dengan koleksi besar di masa lalu dan berpindah dari model yang berdekatan ke model blok, kami dapat menyimpan sekitar 5 kali lebih banyak koleksi sebelum kami kehabisan memori dalam sistem 32-bit. Hal ini sebagian karena, ketika mengalokasikan ulang, sebenarnya diperlukan untuk menyimpan blok lama serta yang baru sebelum menyalin elemen.
Karena itu, Anda bisa mendapatkan masalah dengan std::deque
sistem yang menggunakan alokasi memori "optimis". Sementara upayanya untuk meminta ukuran buffer yang besar untuk realokasi a vector
mungkin akan ditolak di beberapa titik dengan a bad_alloc
, sifat optimis dari pengalokasi kemungkinan akan selalu mengabulkan permintaan untuk buffer yang lebih kecil yang diminta oleh a.deque
dan itu mungkin menyebabkan sistem operasi untuk menghentikan proses untuk mencoba memperoleh beberapa memori. Mana pun yang dipilihnya mungkin tidak terlalu menyenangkan.
Solusi dalam kasus seperti itu adalah menyetel tanda tingkat sistem untuk mengganti alokasi optimis (tidak selalu dapat dilakukan) atau mengelola memori secara lebih manual, misalnya menggunakan pengalokasi Anda sendiri yang memeriksa penggunaan memori atau yang serupa. Jelas tidak ideal. (Yang mungkin menjawab pertanyaan Anda tentang memilih vektor ...)
Saya telah menerapkan vektor dan deque beberapa kali. deque jauh lebih rumit dari sudut pandang implementasi. Komplikasi ini diterjemahkan menjadi lebih banyak kode dan kode yang lebih kompleks. Jadi, Anda biasanya akan melihat ukuran kode yang dipukul saat Anda memilih deque daripada vektor. Anda mungkin juga mengalami sedikit kecepatan hit jika kode Anda hanya menggunakan hal-hal yang unggul di vektor (yaitu push_back).
Jika Anda membutuhkan antrian berujung ganda, deque adalah pemenang yang jelas. Tetapi jika Anda melakukan sebagian besar penyisipan dan penghapusan di bagian belakang, vektor akan menjadi pemenang yang jelas. Jika Anda tidak yakin, nyatakan container Anda dengan typedef (agar mudah beralih), dan ukur.
vector
.) Saya telah menulis implementasi yang ditautkan di bawah ini dalam jawaban saya . Ini bisa secepat vector
tapi lebih banyak diterapkan (misalnya, saat membuat antrian cepat).
std::deque
tidak memiliki jaminan memori berkelanjutan - dan seringkali agak lebih lambat untuk akses yang diindeks. Deque biasanya diimplementasikan sebagai "daftar vektor".
Menurut http://www.cplusplus.com/reference/stl/deque/ , "tidak seperti vektor, deque tidak dijamin memiliki semua elemennya di lokasi penyimpanan yang berdekatan, sehingga menghilangkan kemungkinan akses yang aman melalui aritmatika penunjuk."
Deque sedikit lebih rumit, sebagian karena tidak selalu memiliki tata letak memori yang berdekatan. Jika Anda membutuhkan fitur itu, sebaiknya jangan gunakan deque.
(Sebelumnya, jawaban saya menunjukkan kurangnya standardisasi (dari sumber yang sama seperti di atas, "deques dapat diimplementasikan oleh perpustakaan tertentu dengan cara yang berbeda"), tetapi itu sebenarnya berlaku untuk hampir semua tipe data perpustakaan standar.)
std::deque
tidak kurang standar dari std::vector
. Saya tidak percaya persyaratan kompleksitas untuk std::deque
dapat dipenuhi dengan penyimpanan yang berdekatan.
deque
tidak dapat dipenuhi dengan penyimpanan yang berdekatan?
deque
, yaitu bahwa penyisipan di ujung tidak akan membatalkan referensi ke elemen yang ada. Persyaratan ini menyiratkan memori terputus-putus.
Saya pikir itu ide yang bagus untuk menguji kinerja setiap kasus. Dan buatlah keputusan dengan mengandalkan tes ini.
Saya lebih suka std::deque
daripada std::vector
di kebanyakan kasus.
vector
. Kita dapat menyimpulkan bahwa mengapa tidak wajar. Mengatakan bahwa Anda lebih suka deque
, untuk alasan yang tidak diketahui, dari tes yang tidak ditentukan, bukanlah jawaban.
Anda tidak akan memilih vektor daripada menghapus menurut hasil tes ini (dengan sumber).
Tentu saja, Anda harus menguji di aplikasi / lingkungan Anda, tetapi secara ringkas:
Beberapa renungan lagi, dan catatan untuk dipertimbangkan circular_buffer.
Di satu sisi, vektor sering kali hanya lebih cepat daripada deque. Jika Anda tidak benar-benar membutuhkan semua fitur deque, gunakan vektor.
Di sisi lain, terkadang Anda memang membutuhkan fitur yang tidak diberikan oleh vektor, dalam hal ini Anda harus menggunakan deque. Misalnya, saya menantang siapa pun untuk mencoba menulis ulang kode ini , tanpa menggunakan deque, dan tanpa mengubah algoritme secara drastis.
push_back
dan pop_back
operasi yang sama, deque<int>
selalu setidaknya 20% lebih cepat daripada vector<int>
pada pengujian saya (gcc dengan O3). Saya rasa itulah mengapa deque
pilihan standar untuk hal-hal seperti std::stack
...
Perhatikan bahwa memori vektor dialokasikan kembali saat array bertambah. Jika Anda memiliki pointer ke elemen vektor, mereka akan menjadi tidak valid.
Selain itu, jika Anda menghapus elemen, iterator menjadi tidak valid (tetapi tidak "untuk (otomatis ...)").
Edit: ubah 'deque' menjadi 'vector'
std::deque
memiliki ukuran blok maksimum yang sangat kecil (~ 16 byte, jika saya ingat dengan benar; mungkin 32), dan karena itu tidak bekerja dengan baik untuk aplikasi yang realistis. A dideque<T>
manasizeof(T) > 8
(atau 16? Ini adalah angka kecil) memiliki karakteristik kinerja yang hampir sama dengan avector<T*>
, di mana setiap elemen dialokasikan secara dinamis. Implementasi lain memiliki ukuran blok maksimum yang berbeda, sehingga sulit untuk menulis kode yang memiliki karakteristik kinerja yang relatif sama pada platform yang berbedadeque
.