Francis, First, fix any bugs.
For example, "The benchmark function must run the target code b.N times." https://golang.org/pkg/testing/ Therefore, keyVals := make([]string, b.N*10) // ... for _, key := range keyVals { setOne(s, key) } should be keyVals := make([]string, b.N) // ... for _, key := range keyVals { setOne(s, key) } or s /b.N*10/b.N/ Then, as expected, BenchmarkSetOne-4 1000000 2058 ns/op 159 B/op 0 allocs/op BenchmarkSetTwo-4 1000000 4648 ns/op 319 B/op 0 allocs/op Peter On Friday, September 2, 2016 at 9:07:09 AM UTC-4, Francis wrote: > > I have been working to reduce allocations in a local cache and found some > confusing behaviour around the allocs/op output when benchmarking. > > A simplified reproducing version is pasted at bottom. > > The behaviour is that setting a value in a single map yields 0 > allocations, setting a value in two maps inside the same function yields 1 > allocation. Increasing the number of times the Set*() method is called in > the benchmark (below I am using b.N*10) doesn't change the number of > allocations. > > Trying to track down this I have used GOSSAFUNC to inspect both > setOne(...) and setTwo(...). I couldn't identify any allocations, although > I am not confident in my reading of the SSA output. > > I also ran 'go test -bench=.* -memprofile mem.out' which showed 0 > allocations. > > So I am confused and wanted to ask for clarification on these > measurements. It is interesting to me that the setTwo(...) function > allocates where the setOne(...) does not, but also that the allocations to > the underlying maps don't appear to be recorded by any of the tools I have > used here. > > > package test > > > type server struct { > first map[string]string > second map[string]string > } > > > func new() *server { > return &server{ > first: make(map[string]string), > second: make(map[string]string), > } > } > > > func setOne(s *server, key string) { > s.first[key] = key > } > > > func setTwo(s *server, key string) { > s.first[key] = key > s.second[key] = key > } > > with corresponding benchmark > > > > package test > > > import ( > "strconv" > "testing" > ) > > > func BenchmarkSetOne(b *testing.B) { > keyVals := make([]string, b.N*10) > for i := range keyVals { > keyVals[i] = strconv.Itoa(i) > } > s := &server{ > first: make(map[string]string), > second: make(map[string]string), > } > b.ResetTimer() > b.ReportAllocs() > for _, key := range keyVals { > setOne(s, key) > } > } > > > func BenchmarkSetTwo(b *testing.B) { > keyVals := make([]string, b.N*10) > for i := range keyVals { > keyVals[i] = strconv.Itoa(i) > } > s := &server{ > first: make(map[string]string), > second: make(map[string]string), > } > b.ResetTimer() > b.ReportAllocs() > for _, key := range keyVals { > setTwo(s, key) > } > } > > -- 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. For more options, visit https://groups.google.com/d/optout.