Middle+
Koliko bajtova zauzima mapa (mapa) u Golang?
sobes.tech АИ
Одговор од АИ
Veličina mape u Golangu nije fiksna i zavisi od mnogo faktora:
- Broj elemenata: Što više elemenata, to je potrebnije više memorije za njihovo skladištenje.
- Veličina ključeva i vrednosti: Svaki ključ i vrednost zauzimaju memoriju. Stringovi, slice-ovi, strukture — sve to utiče na ukupnu veličinu.
- Pomoćni podaci strukture
hmap: mapa je pokazivač na strukturuhmap. Ova struktura sadrži pomoćna polja:- brojač elemenata
- pokazivače na kante (buckets)
- brojač migracija (povećanje/smanjenje)
- i druge metapodatke
- Veličina kanti (buckets): elementi se čuvaju u kantama. Svaka kanta ima fiksnu veličinu (obično 8 parova ključ-vrednost), ali podaci o ključevima i vrednostima se čuvaju odvojeno, na koje ukazuju pokazivači iz kante. Kante mogu sadržavati neiskorišćeni prostor.
- Gustoća popunjenosti: Pri dodavanju elemenata, mapa može da se prehash-uje i poveća broj kanti, što zahteva alokaciju nove memorije.
- Poravnanje memorije: Go poravnava podatke u memoriji, što može dovesti do dodatnih bajtova za obezbeđivanje pravilnog pristupa.
Dakle, nije moguće navesti tačan broj bajtova, jer se on dinamički menja u zavisnosti od sadržaja i rasta mape. Može se proceniti donja granica (memorija za hmap i prvu kantu) i gornja granica (zbir veličina ključeva, vrednosti, kanti i pomoćnih podataka), ali tačna veličina je određena runtime-om Go.
Za procenu veličine, može se koristiti paket unsafe ili alati za otklanjanje grešaka, ali oni daju veličinu u konkretnom trenutku za konkretan sadržaj.
// Primer strukture `hmap` ( pojednostavljeno)
// Struktura nije namenjena za direktnu upotrebu
// i njena polja mogu da se menjaju između verzija Go.
type hmap struct {
// Napomena: format `hmap` je opisan u ../runtime/map.go.
// To je hash tabela sa kantama alociranim iz go heap-a.
// hmap.buckets pokazuje na slice od kanti (može biti nil).
// Svaka kanta je niz od `hmap.B` unosa, gde je B veličina kante.
// Pozicija u kanti čuva ključ i vrednost za jedan unos mape,
// plus bajt tophash. Ključevi i vrednosti se čuvaju u istom
// unosu kante, pri čemu vrednosti slede za ključeve.
// Ako su veličine ključeva/vrednosti velike, one se indirektno upisuju u
// overflow kante, počevši od overflow pokazivača u glavnim kantama.
count int // broj živih ćelija; nije 0 ako mapa ima unose
flags uint8
B uint8 // log_2 broja kanti (može da drži do 2^B unosa)
noverflow uint16 // približan broj overflow kanti
hash0 uint32 // seme za hash
buckets unsafe.Pointer // niz od 2^B kanti, alociran na heap-u
oldbuckets unsafe.Pointer // prethodni niz od 2^B kanti, alociran na heap-u
nevacuate uintptr // brojač napretka za evakuaciju (premestanje kanti u nove)
// istina, kada tip ključa ili vrednosti sadrži pokazivače koje treba skenirati
keysize uint8 // veličina tipa ključa
valuesize uint8 // veličina tipa vrednosti
elemsize uint16 // veličina ključa + vrednosti (za in-place skladištenje)
// pokazivač na slice overflow kanti, alociran na heap-u
overflow *[]*bmap
}
// Primer strukture `bmap` ( pojednostavljeno)
// Tip kante.
type bmap struct {
// Raspored kante je složen.
// Detalje pogledajte u src/runtime/hashmap.go.
tophash [8]uint8 // 8 tophash bajtova (po kv par)
// sleduju ključevi i zatim vrednosti
// sleduje overflow pokazivač
}