Posting baru saya terinspirasi oleh kuis go terbaru. Perhatikan tolok ukur [1]:
func BenchmarkSortStrings(b *testing.B) {
s := []string{"heart", "lungs", "brain", "kidneys", "pancreas"}
b.ReportAllocs()
for i := 0; i < b.N; i++ {
sort.Strings(s)
}
}
Sebagai pembungkus yang nyaman sort.Sort(sort.StringSlice(s))
, itu sort.Strings
memodifikasi data yang diteruskan kepadanya, menyortirnya, sehingga tidak semua orang (setidaknya, setidaknya 43% dari pelanggan twitter) dapat berasumsi bahwa ini akan mengarah pada alokasi [alokasi di heap]. Namun, setidaknya dalam versi terbaru Go, ini masalahnya dan setiap iterasi dari tolok ukur ini akan menyebabkan satu alokasi. Tapi kenapa?
Seperti yang harus diketahui oleh banyak pengembang Go, antarmuka diimplementasikan sebagai dua struktur kata (mesin) . Setiap nilai antarmuka berisi dua bidang: satu berisi tipe nilai yang disimpan oleh antarmuka, dan yang lainnya berisi penunjuk ke nilai itu. [2]
Dalam pseudocode, akan terlihat seperti ini:
type interface struct { // , type uintptr // () , data uintptr }
interface.data
, 8 . , , []string
24 : , ; ; (capacity). Go 24 8? , . , []string
24 , *[]string
β 8.
[Escaping]
, sort.Strings
:
func BenchmarkSortStrings(b *testing.B) { s := []string{"heart", "lungs", "brain", "kidneys", "pancreas"} b.ReportAllocs() for i := 0; i < b.N; i++ { var ss sort.StringSlice = s var si sort.Interface = ss // allocation sort.Sort(si) } }
, var si sort.Interface = ss
, var si sort.Interface = &ss
, ss
[3]. , ss
, ? ss
?
, ss
[heap], .
Total: 296.01MB 296.01MB (flat, cum) 99.66% 8 . . func BenchmarkSortStrings(b *testing.B) { 9 . . s := []string{"heart", "lungs", "brain", "kidneys", "pancreas"} 10 . . b.ReportAllocs() 11 . . for i := 0; i < b.N; i++ { 12 . . var ss sort.StringSlice = s 13 296.01MB 296.01MB var si sort.Interface = ss // allocation 14 . . sort.Sort(si) 15 . . } 16 . . }
, , ss
si
(, , , - ). , ss
. , : ? , .
% go test -bench=. sort_test.go goos: darwin goarch: amd64 cpu: Intel(R) Core(TM) i7-5650U CPU @ 2.20GHz BenchmarkSortStrings-4 12591951 91.36 ns/op 24 B/op 1 allocs/op PASS ok command-line-arguments 1.260s
Go 1.16beta1, amd64, 24 [4].
Go 32 .
% go1.15 test -bench=. sort_test.go goos: darwin goarch: amd64 BenchmarkSortStrings-4 11453016 96.4 ns/op 32 B/op 1 allocs/op PASS ok command-line-arguments 1.225s
: Go. , , [size classes].
, , , [] Go 24 . β , . , 24 , 24, . , 24 , , . , , .
, Go 24 , , β , . , . , . ? , .
, , , "", . , 24 , . ? , β [5].
24 , 8 , . 25% "" β , , . ? , 9 , ! - ?
, , . 24- , , , . , β , , - 24- . Go , ( , , , C++). , .
,
, : ? : . , (, ), . .
[6], ( ) . , [7].
, , 9 . , , , 9- . () , , 4. , β . 9 12 . , 3 β , , .
. Go 1.15 24 , ss
32 . Martin MΓΆhrmann Go 1.16 24 , .
[1] , . .
[2] Go. , Go 1.15 . -, .
[3] , sort.StringSlice
, *sort.StringSlice
.
[4] 32 , .
[5] 4G (, , 64 ), , [aligment] [padding] ( , , β . ).
[6] β .
[7] , , .