cmd/gc: apply escape analysis results to closures.
This avoids an allocation when closures are used
as "macros", in Walk idioms, or as argument to defer.
benchmark old ns/op new ns/op delta
BenchmarkSearchWrappers 1171 354 -69.77%
BenchmarkCallClosure 3 3 -12.54%
BenchmarkCallClosure1 119 7 -93.95%
BenchmarkCallClosure2 183 74 -59.18%
BenchmarkCallClosure3 187 75 -59.57%
BenchmarkCallClosure4 187 76 -58.98%
Compared to Go 1:
benchmark old ns/op new ns/op delta
BenchmarkSearchWrappers 3208 354 -88.97%
Fixes #3520.
R=daniel.morsing, bradfitz, minux.ma, dave, rsc
CC=golang-dev
https://golang.org/cl/7397056
diff --git a/src/pkg/sort/search_test.go b/src/pkg/sort/search_test.go
index 07295ff..4d8d6d9 100644
--- a/src/pkg/sort/search_test.go
+++ b/src/pkg/sort/search_test.go
@@ -117,6 +117,28 @@
}
}
+func runSearchWrappers() {
+ SearchInts(data, 11)
+ SearchFloat64s(fdata, 2.1)
+ SearchStrings(sdata, "")
+ IntSlice(data).Search(0)
+ Float64Slice(fdata).Search(2.0)
+ StringSlice(sdata).Search("x")
+}
+
+func TestSearchWrappersDontAlloc(t *testing.T) {
+ allocs := testing.AllocsPerRun(100, runSearchWrappers)
+ if allocs != 0 {
+ t.Errorf("expected no allocs for runSearchWrappers, got %v", allocs)
+ }
+}
+
+func BenchmarkSearchWrappers(b *testing.B) {
+ for i := 0; i < b.N; i++ {
+ runSearchWrappers()
+ }
+}
+
// Abstract exhaustive test: all sizes up to 100,
// all possible return values. If there are any small
// corner cases, this test exercises them.