Closed nar10z closed 4 months ago
v10
Reducing memory allocation by changing map[string]bool/map[string]int -> map[string]strcut{}/map[int]struct{} https://gist.github.com/davecheney/3be245c92b61e5045f75
var iso3166_1_alpha2_eu = map[string]bool{ "AT": true, "BE": true, "BG": true, "HR": true, "CY": true, "CZ": true, "DK": true, "EE": true, "FI": true, "FR": true, "DE": true, "GR": true, "HU": true, "IE": true, "IT": true, "LV": true, "LT": true, "LU": true, "MT": true, "NL": true, "PL": true, "PT": true, "RO": true, "SK": true, "SI": true, "ES": true, "SE": true, } // Change to: var iso3166_1_alpha2_eu = map[string]struct{}{ "AT": {}, "BE": {}, "BG": {}, "HR": {}, "CY": {}, "CZ": {}, "DK": {}, "EE": {}, "FI": {}, "FR": {}, "DE": {}, "GR": {}, "HU": {}, "IE": {}, "IT": {}, "LV": {}, "LT": {}, "LU": {}, "MT": {}, "NL": {}, "PL": {}, "PT": {}, "RO": {}, "SK": {}, "SI": {}, "ES": {}, "SE": {}, }
I made a test that simply prints how much memory a particular map occupies
Bool:
//go:build codes_as_bool package validator import ( "fmt" "testing" "unsafe" ) func printSize[T comparable](t *testing.T, m map[T]bool) { t.Helper() size := unsafe.Sizeof(m) for k, v := range m { size += unsafe.Sizeof(k) size += unsafe.Sizeof(v) } fmt.Printf("Size: %d, bytes: %v\n", len(m), size) } func TestIsoCodesSizes(t *testing.T) { t.Run("iso3166_1_alpha2", func(t *testing.T) { printSize(t, iso3166_1_alpha2) }) t.Run("iso3166_1_alpha2_eu", func(t *testing.T) { printSize(t, iso3166_1_alpha2_eu) }) t.Run("iso3166_1_alpha3", func(t *testing.T) { printSize(t, iso3166_1_alpha3) }) t.Run("iso3166_1_alpha3_eu", func(t *testing.T) { printSize(t, iso3166_1_alpha3_eu) }) t.Run("iso3166_1_alpha_numeric", func(t *testing.T) { printSize(t, iso3166_1_alpha_numeric) }) t.Run("iso3166_1_alpha_numeric_eu", func(t *testing.T) { printSize(t, iso3166_1_alpha_numeric_eu) }) t.Run("iso3166_2", func(t *testing.T) { printSize(t, iso3166_2) }) }
=== RUN TestIsoCodesSizes/iso3166_1_alpha2 Size: 250, bytes: 4258 === RUN TestIsoCodesSizes/iso3166_1_alpha2_eu Size: 27, bytes: 467 === RUN TestIsoCodesSizes/iso3166_1_alpha3 Size: 250, bytes: 4258 === RUN TestIsoCodesSizes/iso3166_1_alpha3_eu Size: 27, bytes: 467 === RUN TestIsoCodesSizes/iso3166_1_alpha_numeric Size: 250, bytes: 2258 === RUN TestIsoCodesSizes/iso3166_1_alpha_numeric_eu Size: 27, bytes: 251 === RUN TestIsoCodesSizes/iso3166_2 Size: 4987, bytes: 84787
Strcut:
//go:build codes_as_struct package validator import ( "fmt" "testing" "unsafe" ) func printSize[T comparable](t *testing.T, m map[T]struct{}) { t.Helper() size := unsafe.Sizeof(m) for k, v := range m { size += unsafe.Sizeof(k) size += unsafe.Sizeof(v) } fmt.Printf("Size: %d, bytes: %v\n", len(m), size) } func TestIsoCodesSizes(t *testing.T) { t.Run("iso3166_1_alpha2", func(t *testing.T) { printSize(t, iso3166_1_alpha2) }) t.Run("iso3166_1_alpha2_eu", func(t *testing.T) { printSize(t, iso3166_1_alpha2_eu) }) t.Run("iso3166_1_alpha3", func(t *testing.T) { printSize(t, iso3166_1_alpha3) }) t.Run("iso3166_1_alpha3_eu", func(t *testing.T) { printSize(t, iso3166_1_alpha3_eu) }) t.Run("iso3166_1_alpha_numeric", func(t *testing.T) { printSize(t, iso3166_1_alpha_numeric) }) t.Run("iso3166_1_alpha_numeric_eu", func(t *testing.T) { printSize(t, iso3166_1_alpha_numeric_eu) }) t.Run("iso3166_2", func(t *testing.T) { printSize(t, iso3166_2) }) }
=== RUN TestIsoCodesSizes/iso3166_1_alpha2 Size: 250, bytes: 4008 === RUN TestIsoCodesSizes/iso3166_1_alpha2_eu Size: 27, bytes: 440 === RUN TestIsoCodesSizes/iso3166_1_alpha3 Size: 250, bytes: 4008 === RUN TestIsoCodesSizes/iso3166_1_alpha3_eu Size: 27, bytes: 440 === RUN TestIsoCodesSizes/iso3166_1_alpha_numeric Size: 250, bytes: 2008 === RUN TestIsoCodesSizes/iso3166_1_alpha_numeric_eu Size: 27, bytes: 224 === RUN TestIsoCodesSizes/iso3166_2 Size: 4987, bytes: 79800
Percentage ~ 7.29%:
iso3166_1_alpha2: 5.87% iso3166_1_alpha2_eu: 5.78% iso3166_1_alpha3: 5.87% iso3166_1_alpha3_eu: 5.78% iso3166_1_alpha_numeric: 11.07% iso3166_1_alpha_numeric_eu: 10.76% iso3166_2: 5.88%
Package version eg. v9, v10:
v10
Enhancement:
Reducing memory allocation by changing map[string]bool/map[string]int -> map[string]strcut{}/map[int]struct{} https://gist.github.com/davecheney/3be245c92b61e5045f75
Code sample, to showcase or reproduce:
I made a test that simply prints how much memory a particular map occupies
Bool:
Strcut:
Percentage ~ 7.29%: