Sobes.tech
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 ցուցիչ: