Sobes.tech
Middle+

Kui palju baitte võtab kaart (map) Golangis?

sobes.tech AI

Vastus AI-lt

Golang-s map-i suurus ei ole fikseeritud ja sõltub paljudest teguritest:

  • Elementide arv: Mida rohkem elemente, seda rohkem mälu on vaja nende salvestamiseks.
  • Võtmete ja väärtuste suurus: Iga võti ja iga väärtus võtavad mälu. Stringid, slyde, struktuurid — kõik see mõjutab üldist suurust.
  • hmap struktuuri teenusandmed: map — see on viide hmap struktuurile. See struktuur sisaldab teenusvälju:
    • elementide arv
    • korvid (buckets) viited
    • migratsioonide (kasv/kitsemine) arv
    • muud metaandmed
  • Korvide suurus (buckets): Elemente hoitakse korvides. Iga korv on fikseeritud suurusega (tavaliselt 8 võti-väärtuspaari), kuid võtmete ja väärtuste andmed salvestatakse eraldi, millele viitavad korvi näitajad. Korvid võivad sisaldada kasutamata ruumi.
  • Täitumuse tihedus: Elementide lisamisel võib map ümber hashida ja suurendada korvide arvu, mis nõuab uut mälu eraldamist.
  • Mälu joondamine: Go joondab andmeid mälus, mis võib kaasa tuua täiendavate baitide kasutamise, et tagada õige juurdepääs.

Seega on võimatu nimetada täpset baitide arvu, kuna see muutub dünaamiliselt sõltuvalt sisust ja map-i kasvust. Võib hinnata madalaimat piiri (hmap ja esimese korvi mälu) ning kõrgeimat piiri (võtmete, väärtuste, korvide ja teenusandmete summa), kuid täpne suurus määratakse Go jooksuaegses keskkonnas.

Suuruse hindamiseks saab kasutada unsafe paketti või silumisvahendeid, kuid need annavad suuruse konkreetse hetke ja konkreetse sisu jaoks.

// Näide `hmap` struktuurist (lihtsustatud)
// Struktuur ei ole mõeldud otse kasutamiseks
// ja selle väljad võivad muutuda Go versioonide vahel.
type hmap struct {
	// `hmap` formaati kirjeldab ../runtime/map.go.
	// See on hash-tabel koos korvidega, mis on eraldatud Go heap-ist.
	// hmap.buckets näitab korvide massiivi (võib olla nil).
	// Iga korv on `hmap.B` elementide massiiv, kus B on korvi suurus.
	// Korvi kirje salvestab ühe map-i kirje võtme ja väärtusega,
	// pluss tophash bait. Võtmed ja väärtused on salvestatud samas
	// korvi kirjes, millele viitavad korvi näitajad.
	// Kui võtme/väärtuse suurus on suur, kirjutatakse need kaudselt üle overflow korvide,
	// alustades overflow näitajatest peamistel korvidel.

	count     int // elusate lahtrite arv; kui mapil on kirjed, ei ole see 0
	flags     uint8
	B         uint8  // korvide arvade logaritm (võib hoida kuni 2^B kirjet)
	noverflow uint16 // ligikaudne overflow korvide arv
	hash0     uint32 // hash seeme

	buckets    unsafe.Pointer // 2^B korvide massiiv, eraldatud heap-is
	oldbuckets unsafe.Pointer // eelmine korvide massiiv, eraldatud heap-is

	nevacuate uintptr // evakueerimise edenemise loendur (korvid on uude siirdatud)

	// tõene, kui võtme või väärtuse tüüp sisaldab näitajaid, mida tuleb skaneerida
	keysize  uint8 // võtme tüübi suurus
	valuesize uint8 // väärtuse tüübi suurus
	elemsize  uint16 // võtme + väärtuse suurus (kohapealseks salvestamiseks)

	// overflow korvide viit, eraldatud heap-is
	overflow *[]*bmap
}

// Näide `bmap` struktuurist (lihtsustatud)
// Korvi tüüp.
type bmap struct {
	// Korvi struktuur on keeruline.
	// Lisateavet vaadake src/runtime/hashmap.go.
	tophash [8]uint8 // 8 tophash baiti (üks iga kv paari kohta)
	// järgneb võtmed ja siis väärtused
	// järgneb overflow näitaja
}