Middle+
Քանի բայթ է զբաղեցնում քարտեզը (մապը) Golang-ում?
sobes.tech AI
Պատասխան AI-ից
Golang- ում քարտեզի չափը փոփոխական է և կախված է բազմաթիվ գործոններից:
- Էլեմենտների քանակը: Որքան շատ է էլեմենտների թիվը, այնքան ավելի շատ հիշողություն է անհրաժեշտ նրանց պահելու համար:
- Բանալիների և արժեքների չափը: Ամեն մի բանալին և արժեքը հիշողություն է զբաղեցնում: Տողեր, slices, կառուցվածքներ — այս բոլորը ազդում են ընդհանուր չափի վրա:
hmapկառուցվածքի օժանդակ տվյալները: քարտեզը ցույց է տալիսhmapկառուցվածքին: Այս կառուցվածքը պարունակում է օժանդակ դաշտեր՝- էլեմենտների հաշվիչը
- ցուցիչներ բաքերի (buckets) վրա
- միգրացիաների հաշվիչը (աճ/կրճատում)
- և այլ մետադատված տվյալներ:
- Բաքերի չափը (buckets): էլեմենտները պահվում են բաքերում: Ամեն բաք ունի ֆիքսված չափ (հաճախ 8 զույգ բանալին-արժեք), բայց բանալիների և արժեքների տվյալները պահվում են առանձին, և բաքից ցուցիչներով հղվում են:
- Լցվածության խտությունը: Ավելացնելիս քարտեզը կարող է վերահաշվարկել և մեծացնել բաքերի քանակը, ինչը պահանջում է նոր հիշողության հատկացում:
- Հիշողության հարթում: Go-ն հարթում է տվյալները հիշողության մեջ, ինչը կարող է հանգեցնել լրացուցիչ բայթների՝ ճիշտ մուտք գործելու համար:
Այսպիսով, ճշգրիտ բայթերի քանակը նշել հնարավոր չէ, քանի որ այն փոփոխվում է բովանդակության և աճի հիման վրա: Կարող է գնահատել նվազագույն (հիշողություն hmap և առաջին բաքի համար) և առավելագույն (բանալիների, արժեքների, բաքերի և օժանդակ տվյալների չափերի գումարը) սահմանները, բայց ճշգրիտ չափը որոշվում է Go-ի ռանթայմով:
Անհրաժեշտ է գնահատելու համար օգտագործել unsafe փաթեթը կամ դետալային գործիքները, բայց դրանք կտան չափը կոնկրետ պահի կոնկրետ բովանդակության համար:
// Օրինակ `hmap` կառուցվածքի (պարզեցված)
// Կառուցվածքը նախատեսված չէ ուղղակի օգտագործման համար
// և նրա դաշտերը կարող են փոխվել տարբեր Go տարբերակներում:
type hmap struct {
// Նշում: `hmap` ձևաչափը նկարագրված է ../runtime/map.go-ում:
// Դա հեշ աղյուսակ է, որի բաքերը հատկացված են Go heap-ից:
// hmap.buckets ցույց է տալիս բաքերի սլայսին (կարող է լինել nil):
// Ամեն բաք՝ `hmap.B` տիպի տարրերի զանգված, B չափով:
// Բաքում տեղադրված է մեկ մուտքագրում՝ բանալին և արժեքը,
// ինչպես նաև tophash բայթը:
// Բանալիները և արժեքները պահվում են նույն բաքի մուտքում,
// արժեքները հաջորդում են բանալիներին:
count int // կենդանի բջիջների քանակը; ոչ զրո, եթե մապում կան մուտքեր
flags uint8
B uint8 // բաքերի քանակի log_2 (կարող է պահել մինչև 2^B մուտք)
noverflow uint16 // մոտավոր overflow բաքերի քանակ
hash0 uint32 // hash սերմ
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` կառուցվածքի (պարզեցված)
// Բաքի տիպ:
// Բաքի դասավորությունը բարդ է:
// մանրամասները տես ../runtime/hashmap.go-ում:
// Դա հեշ աղյուսակ է, որի բաքերը հատկացված են Go heap-ից:
// hmap.buckets ցույց է տալիս բաքերի սլայսին (կարող է լինել nil):
// Ամեն բաք՝ `hmap.B` տիպի տարրերի զանգված, B չափով:
// Բաքի դիրքը պահում է բանալին և արժեքը մեկ մուտքագրում,
// ինչպես նաև overflow ցուցիչ:
// Բաքի դասավորությունը բարդ է:
// Տվյալների մանրամասները տես ../runtime/hashmap.go-ում:
// Դա հեշ աղյուսակ է, որը հատկացված է Go heap-ից:
// hmap.buckets ցույց է տալիս բաքերի սլայսին (կարող է լինել nil):
// Ամեն բաք՝ `hmap.B` տիպի տարրերի զանգված, B չափով:
// Բաքի դիրքը պահում է բանալին և արժեքը մեկ մուտքագրում,
// ինչպես նաև overflow ցուցիչ:
// Բաքի դասավորությունը բարդ է:
// Տվյալների մանրամասները տես ../runtime/hashmap.go-ում:
// Դա հեշ աղյուսակ է, որը հատկացված է Go heap-ից:
// hmap.buckets ցույց է տալիս բաքերի սլայսին (կարող է լինել nil):
// Ամեն բաք՝ `hmap.B` տիպի տարրերի զանգված, B չափով:
// Բաքի դիրքը պահում է բանալին և արժեքը մեկ մուտքագրում,
// ինչպես նաև overflow ցուցիչ: