Sobes.tech
Middle+

Mennyi bájt egy térkép (map) Golangban?

sobes.tech MI

Válasz az MI-től

A Golang térkép mérete nem fix, és sok tényezőtől függ:

  • Elemek száma: Minél több elem van, annál több memóriára van szükség azok tárolásához.
  • Kulcsok és értékek mérete: Minden kulcs és érték memóriát foglal. Szövegek, szeletek, struktúrák — mindez befolyásolja az összméretet.
  • Az hmap struktúra segédadatok: a térkép egy mutató az hmap struktúrára. Ez a struktúra tartalmaz segédmezőket:
    • elemek számláló
    • mutatók a kosarakra (buckets)
    • migrációs számláló (növelés/csökkentés)
    • és más metaadatok
  • A kosarak (buckets) mérete: az elemek a kosarakban tárolódnak. Minden kosár fix méretű (általában 8 kulcs-érték pár), de a kulcsok és értékek adatai külön tárolódnak, és a kosár mutatóival hivatkoznak rájuk. A kosarak tartalmazhatnak nem használt területet.
  • Töltöttség sűrűsége: az elemek hozzáadásakor a térkép újra hash-elhet és növelheti a kosarak számát, ami új memória foglalását igényli.
  • Memória igazítása: a Go igazítja az adatokat a memóriában, ami további bájtokat eredményezhet a helyes hozzáférés biztosítása érdekében.

Ezért nem lehet pontos bájt számot mondani, mivel dinamikusan változik a tartalom és a növekedés függvényében. Becslést lehet adni az alsó határra (az hmap és az első kosár memóriája) és a felső határra (a kulcsok, értékek, kosarak és segédadatok méretének összege), de a pontos méret a Go futásidejű környezetétől függ.

A méret becsléséhez használható az unsafe csomag vagy hibakereső eszközök, de ezek egy adott pillanatban és adott tartalomra adnak méretet.

// Az `hmap` struktúra példája (egyszerűsített)
// A struktúra nem közvetlen használatra készült
// és a mezői változhatnak a Go verziók között.
type hmap struct {
	// Megjegyzés: az `hmap` formátuma a ../runtime/map.go-ban van leírva.
	// Ez egy hash tábla, amely a Go heap-ről foglal kosarakat.
	// Az `hmap.buckets` mutató a kosarak szeletére mutat (lehet nil).
	// Minden kosár az `hmap.B` bejegyzések tömbje, ahol B a kosár mérete.
	// Egy kosárbejegyzés egyetlen térképbejegyzés kulcsát és értékét tárolja,
	// plusz egy tophash bájtot. A kulcsok és értékek ugyanabban a
	// kosárbejegyzésben tárolódnak, az értékek a kulcsok után következnek.
	// Ha a kulcs/érték méretek nagyok, akkor közvetve írják őket overflow kosarakba,
	// kezdve overflow mutatókkal a fő kosarakban.

	count     int // élő cellák száma; nem nulla, ha vannak bejegyzések
	flags     uint8
	B         uint8  // a kosarak számának log2-e (legfeljebb 2^B bejegyzés)
	noverflow uint16 // becsült overflow kosarak száma
	hash0     uint32 // hash mag

	buckets    unsafe.Pointer // 2^B kosár tömbje, a heap-en foglalva
	oldbuckets unsafe.Pointer // korábbi 2^B kosár tömbje, a heap-en foglalva

	nevacuate uintptr // haladási számláló az evakuáláshoz (költöző kosarak)

	// igaz, ha a kulcs vagy érték típus mutatókat tartalmaz, amiket szkennelni kell
	keysize  uint8 // kulcs típusának mérete
	valuesize uint8 // érték típusának mérete
	elemsize  uint16 // kulcs + érték mérete (helyben tárolás)

	// mutató egy overflow kosarak szeletére, a heap-en foglalva
	overflow *[]*bmap
}

// A `bmap` struktúra példája (egyszerűsített)
// Sóbak típus.
type bmap struct {
	// A kosár elrendezése összetett.
	// Részletekért lásd a src/runtime/hashmap.go-t.
	tophash [8]uint8 // 8 tophash bájt (egy minden kv párhoz)
	// követi a kulcsokat és az értékeket
	// követi egy overflow mutató
}