The Go optimizing gc compiler and runtime are working as intended. The results are not strange. Nothing is broken.
Peter On Sunday, May 16, 2021 at 3:07:17 AM UTC-4 tapi...@gmail.com wrote: > > you don't provide the Go version, > > My Go version is Go 1.16.3. (BTW, "go test" really should print Go version > in the first line). > > > you don't provide memory allocation statistics, > > There are no surprises in memory allocation statistics so I didn't mention > them. > > > you only provide results for a single data point. > > There are no surprises for small Ns. So I I didn't provide the results for > them. > > > I am unable reproduce your result. > > At least, you exactly reproduced my first observation: if N is large > enough, the one line implementations are fast as the others. > > And you partially reproduced my second observation: the InsertOneline > implementations > run faster for odd Ns than even Ns for large Ns. > > > On Saturday, May 15, 2021 at 11:49:38 AM UTC-4 peterGo wrote: > >> For your sliceinsert microbenchmarks, you don't provide the Go version, >> you don't provide memory allocation statistics, and you only provide >> results for a single data point. >> >> My results for several values of N: >> >> https://play.golang.org/p/WuKmIy_jY20 >> >> There are significant differences in CPU performance for different values >> of N, ranging from 1:1 to 2:1 for append versus precise implementations. >> >> I am unable reproduce your result. >> >> Peter >> >> On Thursday, May 13, 2021 at 4:52:32 AM UTC-4 tapi...@gmail.com wrote: >> >>> >>> package main >>> >>> import "testing" >>> >>> const N = 1615119 >>> // It is strange that if N is large enough, >>> // the one line implementations are fast as the others. >>> // And if N is odd number, the InsertOneline_Disassemble >>> // implementation is about 10% faster than the others. >>> >>> func init() { >>> println("==================== N =", N) >>> } >>> >>> func InsertOneline(s []int, k int, vs ...int) []int { >>> return append(s[:k], append(vs, s[k:]...)...) >>> } >>> >>> func InsertOneline_Disassemble(s []int, k int, vs ...int) []int { >>> z := append(vs, s[k:]...) >>> return append(s[:k], z...) >>> } >>> >>> func InsertVerbose(s []int, k int, vs ...int) []int { >>> if n := len(s) + len(vs); n <= cap(s) { >>> s2 := s[:n] >>> copy(s2[k+len(vs):], s[k:]) >>> copy(s2[k:], vs) >>> return s2 >>> } >>> s2 := make([]int, len(s) + len(vs)) >>> copy(s2, s[:k]) >>> copy(s2[k:], vs) >>> copy(s2[k+len(vs):], s[k:]) >>> return s2 >>> } >>> >>> >>> func InsertVerbose_b(s []int, k int, vs ...int) []int { >>> if n := len(s) + len(vs); n <= cap(s) { >>> s2 := s[:n] >>> copy(s2[k+len(vs):], s[k:]) >>> copy(s2[k:], vs) >>> return s2 >>> } >>> s2 := make([]int, 0, len(s) + len(vs)) >>> s2 = append(s2, s[:k]...) >>> s2 = append(s2, vs...) >>> s2 = append(s2, s[k:]...) >>> return s2 >>> } >>> >>> func InsertVerbose_c(s []int, k int, vs ...int) []int { >>> if n := len(s) + len(vs); n <= cap(s) { >>> s2 := s[:n] >>> copy(s2[k+len(vs):], s[k:]) >>> copy(s2[k:], vs) >>> return s2 >>> } >>> s2 := append([]int(nil), make([]int, len(s) + len(vs))...)[:0] >>> s2 = append(s2, s[:k]...) >>> s2 = append(s2, vs...) >>> s2 = append(s2, s[k:]...) >>> return s2 >>> } >>> >>> var s1 []int >>> func Benchmark_InsertOneline(b *testing.B) { >>> var x = make([]int, N) >>> var y = make([]int, N/2) >>> var k = N/5 >>> b.ResetTimer() >>> for i := 0; i < b.N; i++ { >>> s1 = InsertOneline(x, k, y...) >>> } >>> } >>> >>> var s1b []int >>> func Benchmark_InsertOneline_Disassemble(b *testing.B) { >>> var x = make([]int, N) >>> var y = make([]int, N/2) >>> var k = N/2 >>> b.ResetTimer() >>> for i := 0; i < b.N; i++ { >>> s1b = InsertOneline_Disassemble(x, k, y...) >>> } >>> } >>> >>> var s2 []int >>> func Benchmark_InsertVerbose(b *testing.B) { >>> var x = make([]int, N) >>> var y = make([]int, N/2) >>> var k = N/2 >>> b.ResetTimer() >>> for i := 0; i < b.N; i++ { >>> s2 = InsertVerbose(x, k, y...) >>> } >>> } >>> >>> var s3 []int >>> func Benchmark_InsertVerbose_b(b *testing.B) { >>> var x = make([]int, N) >>> var y = make([]int, N/2) >>> var k = N/2 >>> b.ResetTimer() >>> for i := 0; i < b.N; i++ { >>> s3 = InsertVerbose_b(x, k, y...) >>> } >>> } >>> >>> var s4 []int >>> func Benchmark_InsertVerbose_c(b *testing.B) { >>> var x = make([]int, N) >>> var y = make([]int, N/2) >>> var k = N/2 >>> b.ResetTimer() >>> for i := 0; i < b.N; i++ { >>> s4 = InsertVerbose_c(x, k, y...) >>> } >>> } >>> >>> >>> The result: >>> >>> $ go test -bench=. -benchtime=3s >>> ==================== N = 1615119 >>> goos: linux >>> goarch: amd64 >>> pkg: a.y/bench/sliceinsert >>> cpu: Intel(R) Core(TM) i5-4210U CPU @ 1.70GHz >>> Benchmark_InsertOneline-4 693 4741509 ns/op >>> Benchmark_InsertOneline_Disassemble-4 871 4194142 ns/op >>> Benchmark_InsertVerbose-4 764 4627334 ns/op >>> Benchmark_InsertVerbose_b-4 769 4958537 ns/op >>> Benchmark_InsertVerbose_c-4 661 4855514 ns/op >>> >> -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/a157ade2-3c8f-48fc-9e9e-9a030edd2c7bn%40googlegroups.com.