私の新しい投稿は、最新の囲碁クイズに触発されました。ベンチマークに注意してください[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)
}
}
周りの便利なラッパーとしてsort.Sort(sort.StringSlice(s))
、それはsort.Strings
誰もが(少なくとも、Twitterの加入者の少なくとも43%)が、これが割り当て[ヒープ上の割り当て]につながることを想定できそうということ、それを並べ替え、それに渡されたデータを変更します。ただし、少なくとも最近のバージョンのGoでは、これが当てはまり、このベンチマークを繰り返すたびに1つの割り当てが発生します。しかし、なぜ?
多くのGo開発者が知っておくべきことですが、インターフェースは2つの(マシン)ワード構造として実装されています。各インターフェイス値には2つのフィールドが含まれます。1つはインターフェイスによって格納された値のタイプを含み、もう1つはその値へのポインタを含みます。[2]
擬似コードでは、次のようになります。
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] , , .