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

go-perftuner

 go-perftuner

Avatar for Oleg Kovalov

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)