我测试了一些函数,但我不明白为什么关闭和匿名函数的时间执行不同:
package main
import (
"fmt"
"time"
)
func X(p *int) {
*p += 1
}
func main() {
n := 1000000000
t0 := time.Now()
for i := 0; i < n; i++ {
p := 0
x := func() {
p += 1
}
x()
}
fmt.Printf("Closure: %v\n", time.Since(t0))
t0 = time.Now()
for i := 0; i < n; i++ {
p := 0
func() {
p += 1
}()
}
fmt.Printf("Anonymous function: %v\n", time.Since(t0))
t0 = time.Now()
for i := 0; i < n; i++ {
p := 0
X(&p)
}
fmt.Printf("Function: %v\n", time.Since(t0))
return
}
结果:
558.84667ms
267.847834ms
271.102576ms
如果我将变量的定义移出循环,则时间相等。
答案 0 :(得分:1)
除此之外,某些代码生成和某些优化比其他方法更容易实现。有关详细信息,请参见Go gc编译器源代码。
$ go version
go version devel +e68ac45172 Fri Jul 20 16:04:01 2018 +0000 linux/amd64
未优化:
$ go test bench_test.go -bench=. -benchmem -gcflags='-N'
goos: linux
goarch: amd64
BenchmarkClosure-4 1 2621664326 ns/op 0 B/op 0 allocs/op
BenchmarkAnonymous-4 1 1995507678 ns/op 0 B/op 0 allocs/op
BenchmarkFunction-4 1 2297303813 ns/op 0 B/op 0 allocs/op
优化:
$ go test bench_test.go -bench=. -benchmem
goos: linux
goarch: amd64
BenchmarkClosure-4 2 585091582 ns/op 0 B/op 0 allocs/op
BenchmarkAnonymous-4 5 287299925 ns/op 0 B/op 0 allocs/op
BenchmarkFunction-4 5 287710165 ns/op 0 B/op 0 allocs/op
bench_test.go
:
package main
import "testing"
func X(p *int) {
*p += 1
}
var N = 1000000000
func BenchmarkClosure(b *testing.B) {
for n := 0; n < b.N; n++ {
for i := 0; i < N; i++ {
p := 0
x := func() {
p += 1
}
x()
}
}
}
func BenchmarkAnonymous(b *testing.B) {
for n := 0; n < b.N; n++ {
for i := 0; i < N; i++ {
p := 0
func() {
p += 1
}()
}
}
}
func BenchmarkFunction(b *testing.B) {
for n := 0; n < b.N; n++ {
for i := 0; i < N; i++ {
p := 0
X(&p)
}
}
}