thực hiện khai báo các đối tượng

Jan 03 2021

Tôi đang viết mã trong một cuộc chinh phục trường đại học nào đó và nhận thấy điều gì đó, khi tôi khai báo một bản đồ trong một vòng lặp chẳng hạn như bên dưới:

for (int i = 0; i < n; i++)
{
    map<int, bool> hashMap;
    //...
}

nó mất nhiều thời gian hơn:

map<int, bool> hashMap;
for (int i = 0; i < n; i++)
{
    hashMap.clear();
    //...
}

vì vậy tôi đã tự hỏi tại sao việc khai báo một đối tượng trong một vòng lặp lại có hiệu suất kém hơn là chỉ khởi tạo lại nó?

Trả lời

2 dxiv Jan 04 2021 at 10:59

Trong phiên bản đầu tiên của mã, hàm tạo và hàm hủy hashMapđược gọi là nlần, trong khi ở phiên bản thứ hai, chúng chỉ được gọi một lần.

Câu hỏi tự nhiên là tại sao việc phá hủy và xây dựng một mapđối tượng mới sẽ khác biệt đáng kể so với việc xóa và tái sử dụng một và cùng một đối tượng. Điều này chỉ có thể được trả lời dứt khoát bằng cách kiểm tra mapmã thực tế của việc triển khai đang được sử dụng, vì vậy sau đây chỉ là một phỏng đoán hợp lý.

std::mapthường được thực hiện bằng cây đỏ-đen , và người ta thường cho việc triển khai cây đỏ-đen để sử dụng một trọng điểm nút cho NIL-lá, xem ví dụ lợi ích của một nút trọng điểm trong một cây đỏ đen? . Lực lượng canh gác này phải được cấp phát mỗi khi cây được xây dựng, sau đó được giải phóng khi bị phá hủy. Ngược lại, thay vào đó , clear'ing a làm maptrống cây nhưng sử dụng lại các đối tượng bên trong được liên kết.

Đối với một ví dụ thực tế về việc triển khai như vậy, hàm tạo của Microsoft _Treegọi tên aptly _Alloc_sentinel_and_proxy();. Vì chúng mapbắt nguồn từ đó _Tree, điều này được gọi mỗi khi một mapđối tượng được xây dựng.