1
0
mirror of https://github.com/golang/go synced 2024-11-12 08:40:21 -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:
Rémy Oudompheng 2013-02-26 00:40:28 +01:00
parent 4692711d7f
commit 9fe60801ae
2 changed files with 27 additions and 1 deletions

View File

@ -238,14 +238,18 @@ 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);
// Force type conversion from *struct to the func type.
clos = nod(OCONVNOP, clos, N);
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;

View File

@ -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.