Upgrade to Pro — share decks privately, control downloads, hide ads and more …

go-perftuner

 go-perftuner

Oleg Kovalov

April 25, 2019
Tweet

More Decks by Oleg Kovalov

Other Decks in Programming

Transcript

  1. Me

  2. func ReadRuneSimple(s string) (ch rune, size int) { if len(s)

    == 0 { return } ch, size = utf8.DecodeRuneInString(s) return } almostInlined example (1)
  3. func ReadRuneSimple(s string) (ch rune, size int) { if len(s)

    == 0 { return } ch, size = utf8.DecodeRuneInString(s) return } $ go-perftuner inl -threshold=100 old.go almostInlined example (1)
  4. func ReadRuneSimple(s string) (ch rune, size int) { if len(s)

    == 0 { return } ch, size = utf8.DecodeRuneInString(s) return } $ go-perftuner inl -threshold=100 old.go $ almostInlined example (1)
  5. func ReadRuneLogged(s string) (ch rune, size int) { if len(s)

    == 0 { return } log.Printf("we're working") ch, size = utf8.DecodeRuneInString(s) return } $ go-perftuner inl -threshold=100 new.go almostInlined example (2)
  6. func ReadRuneLogged(s string) (ch rune, size int) { if len(s)

    == 0 { return } log.Printf("we're working") ch, size = utf8.DecodeRuneInString(s) return } $ go-perftuner inl -threshold=100 new.go inl: ./new.go:34:6: ReadRuneLogged: budget exceeded by 50 almostInlined example (2)
  7. boundChecks example (1) func PutUint32(b []byte, v uint32) { b[0]

    = byte(v) b[1] = byte(v >> 8) b[2] = byte(v >> 16) b[3] = byte(v >> 24) }
  8. boundChecks example (2) func PutUint32(b []byte, v uint32) { b[0]

    = byte(v) b[1] = byte(v >> 8) b[2] = byte(v >> 16) b[3] = byte(v >> 24) } $ go-perftuner bce old.go bce: ./old.go:4:7: slice/array has bound checks bce: ./old.go:5:7: slice/array has bound checks bce: ./old.go:6:7: slice/array has bound checks bce: ./old.go:7:7: slice/array has bound checks $
  9. func PutUint32(b []byte, v uint32) { _ = b[3] //

    early check to guarantee safety b[0] = byte(v) b[1] = byte(v >> 8) b[2] = byte(v >> 16) b[3] = byte(v >> 24) } boundChecks example (3)
  10. boundChecks example (4) func PutUint32(b []byte, v uint32) { _

    = b[3] // early check to guarantee safety b[0] = byte(v) b[1] = byte(v >> 8) b[2] = byte(v >> 16) b[3] = byte(v >> 24) } $ go-perftuner bce new.go bce: ./new.go:4:7: slice/array has bound checks $
  11. boundChecks example (4) func PutUint32(b []byte, v uint32) { if

    len(b) < 4 { return } b[0] = byte(v) b[1] = byte(v >> 8) b[2] = byte(v >> 16) b[3] = byte(v >> 24) } $ go-perftuner bce new.go $
  12. func getRands(size int) []int { nums := make([]int, size) for

    i := range nums { nums[i] = rand.Int() } return nums } escapedVariable example (1)
  13. func getRands(size int) []int { nums := make([]int, size) for

    i := range nums { nums[i] = rand.Int() } return nums } $ go-perftuner esc old.go esc: ./old.go:16:14: make([]int, size) $ escapedVariable example (1)
  14. func sumRand() (total int) { nums := make([]int, 8191) for

    i := range nums { nums[i] = rand.Int() } for _, x := range nums { total += x } return total } escapedVariable example (2)
  15. func sumRand() (total int) { nums := make([]int, 8191) for

    i := range nums { nums[i] = rand.Int() } for _, x := range nums { total += x } return total } $ go-perftuner esc 1.go $ escapedVariable example (3)
  16. func sumRand() (total int) { nums := make([]int, 8191 +

    1) for i := range nums { nums[i] = rand.Int() } for _, x := range nums { total += x } return total } $ go-perftuner esc 1.go escapedVariable example (4)
  17. func sumRand() (total int) { nums := make([]int, 8191 +

    1) for i := range nums { nums[i] = rand.Int() } for _, x := range nums { total += x } return total } $ go-perftuner esc 1.go esc: ./old.go:16:14: make([]int, 8191 + 1) $ escapedVariable example (4)
  18. $ go get golang.org/x/perf/cmd/benchstat $ go test -bench=. -count 10

    > old.txt $ # < do some coding and magic with go-perftuner > $ go test -bench=. -count 10 > new.txt benchstat
  19. benchstat $ go get golang.org/x/perf/cmd/benchstat $ go test -bench=. -count

    10 > old.txt $ # < do some coding and magic with go-perftuner > $ go test -bench=. -count 10 > new.txt $ benchstat old.txt new.txt name old time/op new time/op delta Foo 13.6ms ± 1% 11.8ms ± 1% -13.31% (p=0.016 n=4+5) Bar 32.1ms ± 1% 31.8ms ± 1% ~ (p=0.286 n=4+5)