Saya pra-mengalokasikan sebagian memori ke vector
variabel anggota saya . Kode di bawah ini adalah bagian minimal
class A {
vector<string> t_Names;
public:
A () : t_Names(1000) {}
};
Sekarang di beberapa titik waktu, jika t_Names.size()
sama 1000
. Saya bermaksud menambah ukuran 100
. Kemudian jika sudah tercapai 1100
, kembali naik 100
dan seterusnya.
Pertanyaan saya adalah, apa yang harus dipilih vector::resize()
dan vector::reserve()
. Apakah ada pilihan yang lebih baik dalam skenario seperti ini?
Sunting : Saya memiliki semacam perkiraan yang tepat untuk t_Names
. Saya memperkirakan itu berada di sekitar 700
untuk 800
. Namun dalam situasi (jarang) tertentu , itu dapat tumbuh lebih dari 1000
.
std::vector
.Jawaban:
Kedua fungsi itu melakukan hal yang sangat berbeda!
The
resize()
Metode (dan melewati argumen konstruktor setara dengan itu) akan memasukkan atau menghapus jumlah yang sesuai elemen untuk vektor untuk membuat ukuran itu diberikan (memiliki argumen kedua opsional untuk menentukan nilai mereka). Ini akan mempengaruhisize()
, iterasi akan membahas semua elemen itu, push_back akan menyisipkan setelah mereka dan Anda dapat langsung mengaksesnya menggunakanoperator[]
.The
reserve()
Metode hanya mengalokasikan memori, tapi daun itu uninitialized. Itu hanya mempengaruhicapacity()
, tetapisize()
tidak akan berubah. Tidak ada nilai untuk objek, karena tidak ada yang ditambahkan ke vektor. Jika Anda kemudian memasukkan elemen, tidak ada realokasi yang akan terjadi, karena sudah dilakukan sebelumnya, tetapi itulah satu-satunya efek.Jadi itu tergantung apa yang Anda inginkan. Jika Anda ingin array 1000 item default, gunakan
resize()
. Jika Anda ingin array yang ingin Anda masukkan 1000 item dan ingin menghindari beberapa alokasi, gunakanreserve()
.EDIT: Komentar Blastfurnace membuat saya membaca pertanyaan itu lagi dan menyadari, bahwa dalam kasus Anda, jawaban yang benar adalah jangan mengalokasikan secara manual. Terus masukkan elemen di akhir sesuai kebutuhan. Vektor akan secara otomatis dialokasikan kembali sesuai kebutuhan dan akan melakukannya dengan lebih efisien daripada cara manual yang disebutkan. Satu-satunya kasus yang
reserve()
masuk akal adalah ketika Anda memiliki perkiraan ukuran total yang cukup tepat yang Anda perlukan dengan mudah tersedia sebelumnya.EDIT2: Edit pertanyaan iklan: Jika Anda memiliki taksiran awal, maka
reserve()
taksiran itu. Jika ternyata tidak cukup, biarkan vektor melakukan itu.sumber
vector
.x.reserve(x.size() + newdata); vector<int>::iterator special_element = get_special_element(x); for (int i = 0; i < newdata; ++i) { if some_function(i, special_element) x.push_back(i); }
cukup kuat sejauh menyangkut ruang yang bersangkutan. Saya tidak tahu berapa banyak elemen yang akan ditambahkan, tetapi saya memiliki batas atas. Tentu saja ketika ragu, dengan vektor Anda hanya bisa menggunakan indeks dan bukan iterator, perbedaannya biasanya diabaikan.size()
. "Metode cadangan () hanya mengalokasikan memori" - itu mungkin atau mungkin tidak mengalokasikan memori tergantung pada apakahcapacity()
sudah cukup, mungkin juga perlu memindahkan elemen dan membatalkan alokasi memori asli mereka. "ingin menghindari beberapa alokasi" dan salinan dllresize()
tidak hanya mengalokasikan memori, itu juga menciptakan instance sebanyak ukuran yang Anda inginkanresize()
sebagai argumen. Tetapireserve()
hanya mengalokasikan memori, itu tidak membuat instance. Itu adalah,Output ( demo online ):
Jadi
resize()
mungkin tidak diinginkan, jika Anda tidak ingin objek yang dibuat default. Ini akan lambat juga. Selain itu, jika Andapush_back()
elemen baru untuk itu,size()
vektor akan semakin meningkat dengan mengalokasikan memori baru (yang juga berarti memindahkan elemen yang ada ke ruang memori yang baru dialokasikan). Jika Anda telah menggunakanreserve()
di awal untuk memastikan sudah ada cukup memori yang dialokasikan,size()
vektor akan meningkat ketika Andapush_back()
ke sana, tetapi itu tidak akan mengalokasikan memori baru sampai kehabisan ruang yang Anda pesan untuk itu .sumber
reserve(N)
, kita bisa menggunakannyaoperator []
tanpa bahaya. benar ?reserve
, spesifikasinya hanya mengharuskannya mengalokasikan setidaknya sebanyak itu, sehingga beberapa implementasi dapat mencapai batas tertentu dan dengan demikian menunjukkan kapasitas lebih tinggi dari 1000.v.size()
. Perhatikan bahwareserve(N)
tidak mengubahsize()
vektor.Dari uraian Anda, sepertinya Anda ingin "mencadangkan" ruang penyimpanan yang dialokasikan dari vektor t_Names.
Perhatikan bahwa
resize
inisialisasi vektor yang baru dialokasikan di manareserve
hanya mengalokasikan tetapi tidak membangun. Karenanya, 'cadangan' jauh lebih cepat daripada 'mengubah ukuran'Anda dapat merujuk ke dokumentasi tentang perbedaan ukuran dan cadangan
sumber
cadangan ketika Anda tidak ingin objek diinisialisasi saat dipesan. juga, Anda mungkin lebih suka membedakan secara logis dan melacak penghitungannya dibandingkan penghitungan penggunaannya saat Anda mengubah ukuran. jadi ada perbedaan perilaku di antarmuka - vektor akan mewakili jumlah elemen yang sama saat dipesan, dan akan menjadi 100 elemen lebih besar ketika diubah ukurannya dalam skenario Anda.
itu sepenuhnya tergantung pada tujuan Anda ketika melawan perilaku default. beberapa orang akan menyukai pengalokasi yang disesuaikan - tetapi kami benar-benar membutuhkan ide yang lebih baik tentang apa yang Anda coba selesaikan dalam program Anda untuk memberi saran dengan baik.
Pertama, banyak implementasi vektor hanya akan menggandakan jumlah elemen yang dialokasikan ketika mereka harus tumbuh - apakah Anda mencoba untuk meminimalkan ukuran alokasi puncak atau Anda mencoba memesan ruang yang cukup untuk beberapa program bebas kunci atau sesuatu yang lain?
sumber
operator[]
atau apa pun.