Bagaimana cara mengatur ukuran awal std :: vector?

130

Saya punya vector<CustomClass*>dan saya meletakkan banyak item dalam vektor dan saya perlu akses cepat, jadi saya tidak menggunakan daftar. Bagaimana cara mengatur ukuran awal vektor (misalnya menjadi 20.000 tempat, jadi untuk menghindari salinan ketika saya memasukkan baru)?

Damir
sumber
1
Ada konstruktor dan dua fungsi untuk ini dalam std::vectorreferensi apa pun , tergantung mana yang sesuai dengan kebutuhan Anda dengan lebih baik.
chris
1
Anda tidak dapat menghindari penyalinan dengan hanya menetapkan nilai awal.
juanchopanza
1
Hindari salinan? Menyimpan pointer cukup ringan dalam hal biaya untuk menyalin.
user7116
1
@ Damir, maksud Anda std::vectordalam judul?
Robᵩ

Jawaban:

180
std::vector<CustomClass *> whatever(20000);

atau:

std::vector<CustomClass *> whatever;
whatever.reserve(20000);

Yang pertama menetapkan ukuran sebenarnya dari array - yaitu, membuatnya menjadi vektor 20.000 pointer. Yang terakhir meninggalkan vektor kosong, tetapi cadangan ruang untuk 20.000 pointer, sehingga Anda dapat memasukkan (hingga) banyak tanpa harus realokasi.

Setidaknya dalam pengalaman saya, cukup tidak biasa bagi keduanya untuk membuat perbedaan besar dalam kinerja - tetapi keduanya dapat mempengaruhi kebenaran dalam beberapa keadaan. Secara khusus, selama tidak ada realokasi, iterator ke dalam vektor dijamin tetap valid, dan begitu Anda telah mengatur ukuran / ruang yang dipesan, Anda dijamin tidak akan ada realokasi apa pun selama Anda tidak t meningkatkan ukuran lebih dari itu.

Jerry Coffin
sumber
Manakah dari ini akan lebih efisien untuk sejumlah besar penyisipan / penghapusan?
aktor
3
@ Loggie: Saya ragu akan ada perbedaan dalam efisiensi. Sebagian besar itu mengubah cara Anda menggunakannya - dengan yang pertama, Anda hanya mengarahkan pointer, jadi sesuatu seperti whatever[10000] = somepointer;, di mana yang terakhir mengharuskan Anda untuk push_backsetiap pointer yang Anda tambahkan. Setidaknya jika Anda terbiasa vector, yang terakhir mungkin lebih sederhana dan lebih alami.
Jerry Coffin
Jika ukuran wadah yang disalin diketahui, mengapa tidak lebih efisien untuk ukuran (kembali) dan kemudian menyalin daripada mendorong_back?
1
@Cincinnatus: Karena memiliki panggilan ke reserve, yang mengalokasikan sebelumnya ukuran memori. Secara teori, pengaturan ukuran masih bisa lebih cepat, karena juga menghindari penambahan ukuran saat ini setiap kali Anda menambahkan item. Pada kenyataannya, saya ragu Anda bisa mengukurnya.
Jerry Coffin
1
sebenarnya, jika Anda melakukan ini di jalur panas, dan kode ini disebut banyak, Anda dapat membuat banyak instruksi dan menghemat waktu.
bayindirh
15

Anda perlu menggunakan fungsi cadangan untuk mengatur ukuran yang dialokasikan awal atau melakukannya di konstruktor awal.

vector<CustomClass *> content(20000);

atau

vector<CustomClass *> content;
...
content.reserve(20000);

Ketika Anda reserve()elemen, vectorakan mengalokasikan ruang yang cukup untuk (setidaknya?) Yang banyak elemen. Elemen-elemen tidak ada di dalam vector, tetapi memori siap digunakan. Ini kemudian mungkin akan mempercepat push_back()karena memori sudah dialokasikan.


sumber
Mengalokasikan ukuran juga dapat diberikan selama konstruksi dengan memberikan argumen integral (mis. std::vector<Custom Class*> content(100);)
adelbertc
@ konstruk: Ya, tetapi bisa kurang efisien - dengan jumlah yang sangat kecil.