kinerja mendeklarasikan objek

Jan 03 2021

Saya sedang membuat kode dalam semacam penaklukan universitas dan melihat sesuatu, ketika saya mendeklarasikan peta dalam satu lingkaran seperti di bawah ini:

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

ini membutuhkan lebih banyak waktu daripada:

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

jadi saya bertanya-tanya mengapa mendeklarasikan objek dalam satu lingkaran memiliki kinerja yang lebih buruk daripada hanya menginisialisasi ulang?

Jawaban

2 dxiv Jan 04 2021 at 10:59

Dalam versi pertama kode, konstruktor dan destruktor hashMapdipanggil nkali, sedangkan di versi kedua mereka dipanggil sekali saja.

Pertanyaan alami adalah mengapa merusak dan membangun mapobjek baru akan terlihat berbeda vs. membersihkan dan menggunakan kembali satu objek yang sama. Ini dapat dijawab secara definitif hanya dengan memeriksa mapkode implementasi aktual yang digunakan, jadi berikut ini hanyalah tebakan yang masuk akal.

std::mapbiasanya diimplementasikan dengan menggunakan pohon merah-hitam , dan umum untuk implementasi pohon merah-hitam menggunakan simpul sentinel untuk daun-daun NIL, lihat misalnya Manfaat simpul sentinel dalam pohon merah hitam? . Penjaga ini harus dialokasikan setiap kali pohon dibangun, kemudian dilepaskan saat dihancurkan. Sebaliknya, clear'ing a map, sebaliknya, mengosongkan pohon tetapi menggunakan kembali objek internal terkait.

Untuk contoh nyata dari implementasi seperti itu, _Treekonstruktor Microsoft memanggil nama yang tepat _Alloc_sentinel_and_proxy();. Karena mereka mapberasal dari _Tree, ini dipanggil setiap kali mapobjek dibangun.