mirror of
https://github.com/golang/go
synced 2024-11-12 08:50:22 -07:00
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
This commit is contained in:
parent
4692711d7f
commit
9fe60801ae
@ -238,6 +238,7 @@ walkclosure(Node *func, NodeList **init)
|
||||
}
|
||||
|
||||
clos = nod(OCOMPLIT, N, nod(OIND, typ, N));
|
||||
clos->esc = func->esc;
|
||||
clos->right->implicit = 1;
|
||||
clos->list = concat(list1(nod(OCFUNC, func->closure->nname, N)), func->enter);
|
||||
|
||||
@ -246,6 +247,9 @@ walkclosure(Node *func, NodeList **init)
|
||||
clos->type = func->type;
|
||||
|
||||
typecheck(&clos, Erv);
|
||||
// typecheck will insert a PTRLIT node under CONVNOP,
|
||||
// tag it with escape analysis result.
|
||||
clos->left->esc = func->esc;
|
||||
walkexpr(&clos, init);
|
||||
|
||||
return clos;
|
||||
|
@ -117,6 +117,28 @@ func TestSearchWrappers(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
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.
|
||||
|
Loading…
Reference in New Issue
Block a user