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::vectoruntuk std::deque?
Sejak
Mengapa whould orang lebih memilih std::vectoruntuk std::deque?
Jawaban:
Elemen dalam dequeyang tidak bersebelahan di memori; vectorelemen 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 vectoroperasi yang setara . Di sisi lain, menggunakan banyak / contoh besar dari vectordapat 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 dequepenerapannya 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.
vectorjuga 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 dequekeuntungan 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::dequesistem yang menggunakan alokasi memori "optimis". Sementara upayanya untuk meminta ukuran buffer yang besar untuk realokasi a vectormungkin 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 vectortapi lebih banyak diterapkan (misalnya, saat membuat antrian cepat).
std::dequetidak 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::dequetidak kurang standar dari std::vector. Saya tidak percaya persyaratan kompleksitas untuk std::dequedapat dipenuhi dengan penyimpanan yang berdekatan.
dequetidak 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::dequedaripada std::vectordi 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_backdan pop_backoperasi yang sama, deque<int>selalu setidaknya 20% lebih cepat daripada vector<int>pada pengujian saya (gcc dengan O3). Saya rasa itulah mengapa dequepilihan 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::dequememiliki 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.