Sobes.tech
Middle+

Golang'da xarita (map) qancha bayt oladi?

sobes.tech AI

AIdan javob

Golang'da mapning o'lchami sabit emas va ko'p faktorlar bilan bog'liq:

  • Elementlar soni: Qanchalik ko'p elementlar bo'lsa, ularni saqlash uchun ko'proq xotira kerak bo'ladi.
  • Kalitlar va qiymatlarning o'lchami: Har bir kalit va qiymat xotira egallaydi. Stringlar, slices, tuzilmalar – bularning barchasi umumiy o'lchamga ta'sir qiladi.
  • hmap tuzilmasining xizmat ma'lumotlari: map hmap tuzilmasiga ko'rsatkich. Bu tuzilma xizmat maydonlarini o'z ichiga oladi:
    • elementlar hisoblagichi
    • bucketlarga ko'rsatkichlar
    • migratsiya hisoblagichi (o'sishi/kamayishi)
    • va boshqa metama'lumotlar
  • Bucketlarning o'lchami: Elementlar bucketlarda saqlanadi. Har bir bucket belgilangan o'lchamga ega (odatda 8 ta kalit-qiymat juftligi), ammo kalitlar va qiymatlar alohida saqlanadi, bucket ichidagi ko'rsatkichlar bilan ko'rsatiladi. Bucketlar foydalanilmaydigan bo'sh joylarni o'z ichiga olishi mumkin.
  • To'ldirish zichligi: Elementlar qo'shilganda, map qayta hashlanishi va bucketlar soni ko'payishi mumkin, bu esa yangi xotira ajratishni talab qiladi.
  • Xotira moslamasi: Go ma'lumotlarni xotirada moslaydi, bu esa to'g'ri kirishni ta'minlash uchun qo'shimcha baytlarni kiritishi mumkin.

Shuning uchun, aniq baytlar sonini aytib bo'lmaydi, chunki u dinamik ravishda o'zgaradi, mazmun va mapning o'sishi bilan. Pastki chegarani ( hmap va birinchi bucket uchun xotira) va yuqori chegarani (kalitlar, qiymatlar, bucketlar va xizmat ma'lumotlarining o'lchamlari yig'indisi) baholash mumkin, ammo aniq o'lcham Go runtime tomonidan belgilanadi.

O'lchamni baholash uchun unsafe paketidan yoki debugging vositalaridan foydalanish mumkin, ammo ular faqat ma'lum bir vaqtda va ma'lum bir mazmun uchun o'lchamni ko'rsatadi.

// Soddalashtirilgan `hmap` tuzilmasi misoli
// Bu tuzilma to'g'ridan-to'g'ri foydalanish uchun mo'ljallanmagan
// va uning maydonlari Go versiyalariga qarab o'zgarishi mumkin.
type hmap struct {
	// `hmap` formati ../runtime/map.go da tavsiflangan.
	// Bu Go yotqizmasidan ajratilgan bucket bilan hash jadvali.
	// hmap.buckets Go yotqizmasidan ajratilgan bucketlar slice'iga ishora qiladi (nil bo'lishi mumkin).
	// Har bir bucket, B bucket o'lchamiga ega bo'lgan hmap.B kirishlarining massividir.
	// Bir bucket kirishi, map kiridi uchun kalit va qiymatni saqlaydi,
	// shuningdek, tophash baytini. Kalitlar va qiymatlar bir
	// bucket kirishida saqlanadi, qiymatlar kalitlarning keyingi joyida.
	// Agar kalit/qimmat o'lchamlari katta bo'lsa, ular to'liq bo'lmagan bucketlarga yoziladi,
	// overflow ko'rsatkichlari bilan boshlanadi.

	count     int // jonli hujayralar soni; 0 dan farq qilsa, mapda kirishlar bor
	flags     uint8
	B         uint8  // bucketlar sonining log_2 qiymati (2^B gacha bo'lishi mumkin)
	noverflow uint16 // taxminiy overflow bucketlar soni
	hash0     uint32 // hash urug'i

	buckets    unsafe.Pointer // 2^B bucketlar massiviga, heap'da ajratilgan
	oldbuckets unsafe.Pointer // avvalgi 2^B bucketlar massiviga, heap'da ajratilgan

	nevacuate uintptr // evakuatsiya uchun progress counter (bucketlar yangi joyga ko'chirilgan)

	// kalit yoki qiymat turi pointerlar bo'lsa, skanerlash kerak
	keysize  uint8 // kalit turi o'lchami
	valuesize uint8 // qiymat turi o'lchami
	elemsize  uint16 // kalit + qiymat o'lchami (joyda saqlash uchun)

	// overflow bucketlar slice'iga pointer, heap'da ajratilgan
	overflow *[]*bmap
}

// Soddalashtirilgan bmap tuzilmasi misoli
// Bucket turi.
type bmap struct {
	// Bucketning tuzilishi murakkab.
	// Detallar uchun src/runtime/hashmap.go ga qarang.
	tophash [8]uint8 // 8 tophash bayti (bir juftlik uchun)
	// keylar va keyingi qiymatlar
	// overflow ko'rsatkichiga o'tadi
}