Làm cách nào để đặt kích thước ban đầu của std :: vector?


130

Tôi có một vector<CustomClass*>và tôi đặt rất nhiều vật phẩm vào vector và tôi cần truy cập nhanh, vì vậy tôi không sử dụng danh sách. Làm cách nào để đặt kích thước ban đầu của vectơ (ví dụ là 20 000 vị trí, để tránh sao chép khi tôi chèn mới)?


1
Có một hàm tạo và hai hàm cho điều này trong bất kỳ std::vectortham chiếu nào , tùy theo nhu cầu của bạn phù hợp hơn với nhu cầu của bạn.
chris

1
Bạn không thể tránh việc sao chép chỉ là thiết lập giá trị ban đầu.
juanchopanza

1
Tránh bản sao của? Lưu trữ con trỏ là khá nhẹ về chi phí để sao chép.
dùng7116


1
@Damir, ý bạn là std::vectortrong tiêu đề?
Rob

Câu trả lời:


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

hoặc là:

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

Cái trước đặt kích thước thực của mảng - tức là làm cho nó trở thành một vectơ 20000 con trỏ. Cái sau để trống vector, nhưng dành không gian cho 20000 con trỏ, vì vậy bạn có thể chèn (tối đa) nhiều cái mà không cần phải phân bổ lại.

Ít nhất theo kinh nghiệm của tôi, việc một trong hai điều này tạo ra sự khác biệt lớn về hiệu suất - nhưng có thể ảnh hưởng đến tính chính xác trong một số trường hợp. Đặc biệt, miễn là không xảy ra việc tái phân bổ, các trình lặp vào vectơ được đảm bảo vẫn hợp lệ và một khi bạn đã đặt kích thước / không gian dành riêng, bạn sẽ được đảm bảo sẽ không có bất kỳ sự phân bổ nào miễn là bạn không ' t tăng kích thước hơn thế.


Điều nào trong số này sẽ hiệu quả hơn đối với một số lượng lớn các thao tác chèn / xóa?
ctor

3
@Loggie: Tôi nghi ngờ sẽ có bất kỳ sự khác biệt nào về hiệu quả. Chủ yếu là nó thay đổi cách bạn sử dụng nó - với cái trước, bạn chỉ cần giải quyết các con trỏ, vì vậy một cái gì đó như whatever[10000] = somepointer;, trong đó cái sau yêu cầu bạn đến push_backtừng con trỏ bạn thêm. Ít nhất nếu bạn đã quen vector, cái sau có lẽ đơn giản và tự nhiên hơn.
Jerry Coffin

Nếu kích thước của container được sao chép từ được biết đến, tại sao nó không hiệu quả hơn để (tái) kích thước và sau đó sao chép thay vì đẩy_back?

1
@Cincinnatus: Bởi vì nó có lệnh gọi reserve, phân bổ trước kích thước bộ nhớ. Về lý thuyết, việc đặt kích thước vẫn có thể nhanh hơn một chút, vì nó cũng tránh tăng kích thước hiện tại mỗi khi bạn thêm một mục. Trong thực tế, tôi nghi ngờ bạn có thể đo lường điều đó mặc dù.
Jerry Coffin

1
thực tế, nếu bạn đang làm điều này trên một đường dẫn nóng và mã được gọi rất nhiều, bạn có thể thực hiện nhiều hướng dẫn và tiết kiệm thời gian.
bayindirh

15

Bạn cần sử dụng hàm dự trữ để đặt kích thước được phân bổ ban đầu hoặc thực hiện trong hàm tạo ban đầu.

vector<CustomClass *> content(20000);

hoặc là

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

Khi bạn reserve()yếu tố, vectorsẽ phân bổ đủ không gian cho (ít nhất là?) Nhiều yếu tố. Các phần tử không tồn tại trong vector, nhưng bộ nhớ đã sẵn sàng để sử dụng. Điều này sau đó có thể tăng tốc push_back()vì bộ nhớ đã được phân bổ.


Phân bổ kích thước cũng có thể được cung cấp trong quá trình xây dựng bằng cách chuyển vào một đối số không thể tách rời (ví dụ std::vector<Custom Class*> content(100);)
adelbertc

@kstruct: Có, nhưng nó có thể kém hiệu quả hơn - bằng một lượng rất nhỏ.
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.