Sobes.tech
Middle+

Golang-da xəritə (map) neçə bayt tutar?

sobes.tech Süni İntellekt

AI-dan cavab

Golang-də xəritənin ölçüsü sabit deyil və çox faktora bağlıdır:

  • Elementlərin sayı: Elementlər nə qədər çox olarsa, yaddaş da bir o qədər çox tələb edir.
  • Açarlar və dəyərlərin ölçüsü: Hər bir açar və dəyər yaddaş tutar. Sətirlər, səyrlər, strukturlar — bunların hamısı ümumi ölçüyə təsir edir.
  • hmap strukturunun köməyinə aid məlumatlar: xəritə — hmap strukturuna göstəricidir. Bu struktur köməyinə aid sahələri ehtiva edir:
    • elementlərin sayğacı
    • səbətlərin (buckets) göstəriciləri
    • köçürmələrin (artırma/azaltma) sayğacı
    • və digər metadatalar
  • Səbətlərin ölçüsü (buckets): Elementlər səbətlərdə saxlanılır. Hər səbət sabit ölçüyə malikdir (adətən 8 açar-dəyər cütlüyü), lakin açar və dəyərlər müstəqil şəkildə saxlanılır və səbətdən göstəricilərlə göstərilir. Səbətlər istifadə olunmayan sahələrə malik ola bilər.
  • Doldurma sıxlığı: Elementlər əlavə edilərkən xəritə yenidən xəritələşdirilə və səbətlərin sayını artıra bilər, bu da yeni yaddaş ayırmağı tələb edir.
  • Yaddaşın hizalanması: Go yaddaş məlumatlarını hizalayır, bu da əlavə baytların istifadəsinə səbəb ola bilər.

Beləliklə, dəqiq bayt sayını söyləmək mümkün deyil, çünki bu, məzmun və xəritənin böyüməsinə görə dinamik dəyişir. hmap və ilk səbət üçün aşağı sərhədi və açarların, dəyərlərin, səbətlərin və köməyinə aid məlumatların ümumi ölçüsünü qiymətləndirmək olar, lakin dəqiq ölçü Go vaxtı ilə müəyyən edilir.

Ölçünü qiymətləndirmək üçün unsafe paketindən və ya diaqnostik alətlərdən istifadə etmək mümkündür, lakin onlar konkret an üçün və konkret məzmun üçün ölçü verəcək.

// `hmap` strukturunun nümunəsi (sadələşdirilmiş)
// Bu struktur birbaşa istifadə üçün nəzərdə tutulmayıb
// və onun sahələri Go versiyalarına görə dəyişə bilər.
type hmap struct {
	// Qeyd: `hmap` formatı ../runtime/map.go-də təsvir olunub.
	// Bu, yaddaşdan ayrılmış səbətləri olan bir xəritədir.
	// hmap.buckets göstəricisi səbət diliminə işarə edir (nil ola bilər).
	// Hər səbət `hmap.B` girişindən ibarət olan massivdir, burada B səbət ölçüsüdür.
	// Səbət girişləri bir xəritə girişinin açar və dəyərini saxlayır,
	// və tophash baytını ehtiva edir. Açarlar və dəyərlər eyni səbət girişində saxlanılır,
	// və dəyərlər açarların ardınca gəlir.
	// Əgər açar/dəyər ölçüləri böyükdürsə, onlar müstəqil olaraq overflow səbətlərində yazılır,
	// və əsas səbətlərdə overflow göstəriciləri vasitəsilə keçid edilir.

	count     int // canlı hüceyrələrin sayı; map-də heç bir giriş yoxdursa, 0-dan fərqli
	flags     uint8
	B         uint8  // səbətlərin log_2 sayı (2^B-ə qədər giriş saxlaya bilər)
	noverflow uint16 // təxmini overflow səbətlərin sayı
	hash0     uint32 // hash toxumu

	buckets    unsafe.Pointer // 2^B səbətinin massivinə göstərici, heap-də ayrılıb
	oldbuckets unsafe.Pointer // əvvəlki 2^B səbətinin massivinə göstərici, heap-də ayrılıb

	nevacuate uintptr // köçürmə üçün irəliləyiş göstəricisi (səbətlər yeni yerə köçürülür)

	// Açar və dəyər tiplərində göstəricilər var ki, göstəricilərə ehtiyac duyurlar
	keysize  uint8 // açar tipinin ölçüsü
	valuesize uint8 // dəyər tipinin ölçüsü
	elemsize  uint16 // açar + dəyər ölçüsü (daxili saxlama üçün)

	// overflow səbətinin diliminə göstərici, heap-də ayrılıb
	overflow *[]*bmap
}

// `bmap` strukturunun nümunəsi (sadələşdirilmiş)
// Səbət tipi.
type bmap struct {
	// Səbət quruluşu mürəkkəbdir.
	// Ətraflı məlumat üçün src/runtime/hashmap.go-ya baxın.
	tophash [8]uint8 // 8 tophash baytı (hər kv cütü üçün bir)
	// ardınca açarlar və sonra dəyərlər
	// və overflow göstəricisi
}