Middle+
Golangда карта (мапа) канча байтты ээлейтет?
sobes.tech AI
AIден жооп
Golang-догу карта өлчөмү такыр эмес жана көптөгөн факторлорго көз каранды:
- Элементтердин саны: Элементтер канчалык көп болсо, ошончолук көбүрөөк эс тутум керек болот.
- Ключтөрдүн жана маанилердин өлчөмү: Ар бир ачкыч жана маанилер эс тутумду ээлейт. Тексттер, слайстар, структуралар — булардын баары жалпы өлчөмгө таасир этет.
hmapструктурасынын жардамчы маалыматтары: картаhmapструктурасына көрсөтүүчү. Бул структура жардамчы талааларга ээ:- элементтердин санын эсептегич
- кошулмаларга (buckets) көрсөтүүчүлөр
- миграциялардын эсептегичи (өскөн/азайган)
- жана башка метадата
- Кошулмалардын (buckets) өлчөмү: элементтер кошулмаларда сакталат. Ар бир кошулма белгилүү өлчөмгө ээ (адатта 8 ачкыч-баа жупу), бирок ачкычтар жана баалар өзүнчө сакталат, жана кошулмадан көрсөтүүчүлөр аркылуу шилтеме жасалат. Кошулмаларда колдонулбаган орундар болушу мүмкүн.
- Толтуруу тыгыздыгы: Элементтер кошулмаларды кошуу менен карта кайра хештелип, кошулмалардын санын көбөйтүшү мүмкүн, бул жаңы эс тутумду бөлүүнү талап кылат.
- Эс тутумдун тууралаштырылышы: Go маалыматтарды эс тутумда тууралаштырат, бул туура жетүүнү камсыз кылуу үчүн кошумча байттарды алып келиши мүмкүн.
Ошондуктан, так байт санын аташ мүмкүн эмес, анткени ал мазмун жана карта өсүшүнө жараша динамикалык өзгөрөт. Анын төмөнкү чеги (hmap жана биринчи кошулманын эс тутуму) жана жогорку чеги (ачкычтардын, баалардын, кошулмалардын жана жардамчы маалыматтардын өлчөмдөрүнүн жыйындысы) бааланса болот, бирок так өлчөмү Go runtime тарабынан аныкталат.
Өлчөмүн баалоо үчүн unsafe пакети же диагностикалык инструменттер колдонулушу мүмкүн, бирок алар конкреттүү учур үчүн конкреттүү мазмундун өлчөмүн берет.
// `hmap` структурасынын мисалы (жөнөкөйлөштүрүлгөн)
// Структура түздөн-түз колдонууга арналган эмес
// жана анын талаалары версиялар арасында өзгөрүшү мүмкүн:
type hmap struct {
// Эскертүү: `hmap` форматы ../runtime/map.goда сүрөттөлгөн.
// Бул Go heapтен бөлүнгөн кошулмалар менен хеш таблицасы:
// hmap.buckets көрсөтүүчү, ал nil болушу мүмкүн.
// Ар бир кошулма `hmap.B` массиви, B өлчөмүндө:
// Бир кошулмада бир карта жазуусу үчүн ачкыч жана мааниси сакталат,
// жана tophash байт. Ачкычтар жана маанилер бир эле
// кошулма жазуусунда сакталат, маанилер ачкычтардан кийинки келет.
// Эгер ачкычтар жана маанилер чоң болсо, алар космостук кошулмаларга жазылат,
// жана негизги кошулмаларда overflow көрсөткүчтөрү аркылуу шилтеме жасалат.
count int // тирүү клеткалардын саны; 0 эмес, эгер картада жазуулар болсо
flags uint8
B uint8 // кошулмалардын лог_2 саны (максимум 2^B жазууларды сактай алат)
noverflow uint16 // болжолдуу overflow кошулмалардын саны
hash0 uint32 // хеш уруктуу
buckets unsafe.Pointer // 2^B кошулмалар массиви, heapте бөлүнгөн
oldbuckets unsafe.Pointer // мурдагы 2^B кошулмалар массиви, heapте бөлүнгөн
nevacuate uintptr // эвакуациянын прогресс индекси (кошулмаларды жаңы жерге которуу)
// туура келгенде, ачкыч же маанинин тиби көрсөткүчтөрдү камтыйт, алар сканерлениши керек
keysize uint8 // ачкыч тибинин өлчөмү
valuesize uint8 // маанинин тибинин өлчөмү
elemsize uint16 // ачкыч + маанинин өлчөмү (ишке киргизүү үчүн)
// overflow кошулмалардын срезине көрсөткүч, heapте бөлүнгөн
overflow *[]*bmap
}
// `bmap` структурасынын мисалы (жөнөкөйлөштүрүлгөн)
// Кошулма тиби.
type bmap struct {
// Кошулманын жайгашуусу татаал.
// Толугураак маалымат үчүн ../runtime/hashmap.go караңыз.
// Бул хеш таблица, ал кошулмалардан бөлүнгөн, Go heapтен бөлүнгөн.
// hmap.buckets көрсөткүчү кошулмалардын срезине (мүмкүн болсо nil)
// көрсөтөт.
// Ар бир кошулма `hmap.B` массиви, B өлчөмүндө:
// Кошулмада бир карта жазуусу үчүн ачкыч жана мааниси сакталат,
// жана overflow көрсөткүчү.
}