Middle+
Golang-ში რუკა (მაპა) რამდენ ბაიტს იკავებს?
sobes.tech AI
პასუხი AI-სგან
Golang-да map-тың өлшемі тұрақты емес және көптеген факторларға байланысты:
- Элементтердің саны: Элементтер саны көп болған сайын, оларды сақтау үшін көп жад қажет.
- Кілттер мен мәндердің өлшемі: Әр кілт пен әр мән жадты алады. Жолдар, слайстар, құрылымдар — бұлар жалпы өлшемге әсер етеді.
hmapқұрылымының қызметтік деректері: map — бұлhmapқұрылымына сілтеме. Бұл құрылымда қызметтік өрістер бар:- элементтер саны
- себеттерге (buckets) сілтемелер
- көшірулер (өсу/азайту) саны
- басқа метадеректер
- Себеттердің өлшемі (buckets): Элементтер себеттерде сақталады. Әр себет тұрақты өлшемге ие (әдетте 8 кілт-мән жұбы), бірақ кілттер мен мәндердің деректері бөлек сақталады, себеттегі көрсеткіштер арқылы сілтемеленеді. Себеттерде пайдаланылмаған орын болуы мүмкін.
- Толымдылық тығыздығы: Элементтер қосқанда map қайта хештелуі мүмкін және себеттер саны өседі, бұл жаңа жад бөлуін талап етеді.
- Жадыны туралау: Go деректерді жадыда туралайды, бұл қосымша байттарды қажет етуі мүмкін дұрыс қол жеткізу үшін.
Осылайша, нақты байт санын атау мүмкін емес, себебі ол мазмұн мен map-тың өсуіне байланысты динамикалық түрде өзгереді. Төменгі шекара ( hmap және алғашқы себет үшін) және жоғарғы шекара (кілттер, мәндер, себеттер және қызметтік деректердің сомасы) бағалана алады, бірақ нақты өлшем Go-ның рантаймына тәуелді.
Өлшемді бағалау үшін unsafe пакетін немесе дебаг құралдарын қолдануға болады, бірақ олар нақты уақыттағы мазмұнға сәйкес өлшемді береді.
// `hmap` құрылымының мысалы (қарапайым)
// Бұл құрылым тікелей қолдануға арналмаған
// және оның өрістері Go нұсқаларына қарай өзгеруі мүмкін.
type hmap struct {
// `hmap` форматы ../runtime/map.go файлында сипатталған.
// Бұл хэш кестесі, себеттер Go heap-тан бөлінген.
// hmap.buckets көрсеткіші себеттердің тізіміне сілтеме жасайды (nil болуы мүмкін).
// Әр себет `hmap.B` элементтерінен тұрады, мұнда B себеттің өлшемі.
// Себеттегі әрбір элемент бір map жазбасының кілті мен мәнін сақтайды,
// plus tophash байты. Кілттер мен мәндер бір себет жазбасында сақталады,
// мәндер кілттердің соңында орналасады.
// Егер кілт/мән өлшемдері үлкен болса, олар жанама түрде overflow себеттеріне жазылады,
// overflow көрсеткіштері арқылы негізгі себеттерден басталады.
count int // тірі ұяшықтар саны; map-те қандай да бір жазбалар болса, 0-ден басқа
flags uint8
B uint8 // себеттер санының логарифмі (2^B дейін орналастыра алады)
noverflow uint16 // шамамен overflow себеттер саны
hash0 uint32 // хэш тұқым
buckets unsafe.Pointer // 2^B себеттерінің массиві, heap-те бөлінген
oldbuckets unsafe.Pointer // алдыңғы себеттердің массиві, heap-те бөлінген
nevacuate uintptr // эвакуацияның прогрессі (көшіру себеттері)
// кілт немесе мән типінде көрсеткіштер бар, олар сканерлеуді қажет етеді
keysize uint8 // кілт типінің өлшемі
valuesize uint8 // мән типінің өлшемі
elemsize uint16 // кілт + мән өлшемі (орында сақтау үшін)
// overflow себеттерінің тізіміне көрсеткіш, heap-те бөлінген
overflow *[]*bmap
}
// `bmap` құрылымының мысалы (қарапайым)
// Себет типі.
type bmap struct {
// Себеттің құрылымы күрделі.
// Толығырақ үшін src/runtime/hashmap.go қараңыз.
tophash [8]uint8 // 8 tophash байты (бірі әр kv жұбы үшін)
// одан әрі кілттер мен мәндер
// overflow көрсеткіші
}