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

Essentials of Golang

Essentials of Golang

Presentation for Go All-stars 2

Shintaro Kaneko

October 02, 2016
Tweet

More Decks by Shintaro Kaneko

Other Decks in Programming

Transcript

  1. Essentials of Golang
    kaneshin (Shintaro Kaneko) at eureka, Inc.

    View Slide

  2. @kaneshin (Shintaro Kaneko)
    - Principal Engineer / Manager
    - Gopher, Vimmer, Photographer, Mathematician

    View Slide

  3. 'BDFCPPLΛར༻ͨ͠
    ࿀Ѫɾࠗ׆ϚονϯάαʔϏε

    View Slide

  4. Agenda
    • Go Proverbs
    • Constants
    • Testing
    • regexp.Regexp
    • Summaries

    View Slide

  5. Go Proverbs

    View Slide

  6. Go Proverbs
    • Go Proverbs - Rob Pike - Gopherfest - November 18, 2015
    • https://www.youtube.com/watch?v=PAAkCSZUG1c
    • go-proverbs.github.io
    • https://go-proverbs.github.io

    View Slide

  7. Go Proverbs - Rob Pike - Gopherfest

    View Slide

  8. Go Proverbs
    • Don't communicate by sharing memory, share memory by
    communicating.
    • The bigger the interface, the weaker the abstraction.
    • Gofmt's style is no one's favorite, yet gofmt is everyone's favorite.
    • A little copying is better than a little dependency.
    • Clear is better than clever.
    • Reflection is never clear.
    • etc..

    View Slide

  9. Constants

    View Slide

  10. Constants
    • Constants are interpreted at compile-time
    • Definable;
    • Numbers, characters (runes), strings or booleans
    • Evaluatable;
    • ⭕ Thousand = 10 * 3, KB = 1 << 3
    • Arithmetic and Bit operations
    • ❌ math.Pow(10, 3)
    • math.Pow needs to happen at run time.

    View Slide

  11. Constants
    const (
    likeFromMe = 1 << 0
    likeFromPartner = 1 << 1
    blockFromMe = 1 << 2
    blockFromPartner = 1 << 3
    mutualLike = likeFromMe | likeFromPartner
    )
    func main() {
    // do something
    if status^mutualLike == 0 {
    fmt.Printf("Matching status: %b\n", status)
    }
    }

    View Slide

  12. Constants w/ iota

    View Slide

  13. Constants with iota
    • The ninth letter of the Greek alphabet (Ι, ι)
    • Pronunciations;
    • ೔ຊਓɿΠΦλ
    • ֎ਓɿōŘśŏŦ (ʌɪˈəʊtə)
    • Enumeration constants
    • Expressions can be implicitly repeated

    View Slide

  14. Constants with iota
    const (
    likeFromMe = 1 << iota // 1 (1 << 0)
    likeFromPartner // 10 (1 << 1)
    blockFromMe // 100 (1 << 2)
    blockFromPartner // 1000 (1 << 3)
    index = iota // 4
    mask = 1<mutualLike = likeFromMe | likeFromPartner
    )

    View Slide

  15. Constants w/ type

    View Slide

  16. Constants with type
    • Constants can be set user-defined type

    View Slide

  17. Constants with type
    type relationshipStatus uint32
    const (
    likeFromMe relationshipStatus = 1 << iota
    likeFromPartner
    blockFromMe
    blockFromPartner
    mutualLike = likeFromMe | likeFromPartner
    )
    func (st relationshipStatus) isMatching() bool {
    return st^mutualLike == 0
    }
    // if status.isMatching() { .. }

    View Slide

  18. Constants - others
    // _ = iota instead of iota + 1
    const (
    _ = iota // ignore first value by assigning to blank identifier
    KB uint64 = 1 << (10 * iota)
    MB
    GB
    )
    // If you use iota + 1 for above example, don't forget parenthesis of "iota + 1".
    // ⭕ 1 << (10 * (iota + 1))
    // ❌ 1 << (10 * iota + 1)
    // Available for constants to assign other package constants.
    const Day = 24 * time.Hour // time.Hour is constant.
    // ❌ var Day = 24 * time.Hour

    View Slide

  19. Testing

    View Slide

  20. • Table-driven tests
    • https://github.com/golang/go/wiki/TableDrivenTests
    • https://golang.org/src/regexp/all_test.go
    • Run tests by parallel rather than sequential
    • To save your time
    • To detect race condition
    Testing Techniques

    View Slide

  21. Table-driven tests

    View Slide

  22. Table-driven tests
    func TestToUpper(t *testing.T) {
    // Table-driven tests
    candidates := []struct {
    src, expected string
    }{
    {"foo", "FOO"}, {"bar", "BAR"},
    }
    for _, c := range candidates {
    actual := strings.ToUpper(c.src)
    if c.expected != actual {
    // should be good error messages.
    t.Fatalf("Expected %v, but got %v\n", c.expected, actual)
    }
    }
    }

    View Slide

  23. Parallelize Tests

    View Slide

  24. Parallelize Tests
    -To save your time-

    View Slide

  25. Parallelize tests
    func TestSimple(t *testing.T) {
    // Table-driven tests
    candidates := []struct {
    dur time.Duration
    }{
    {time.Second}, {2 * time.Second}, {3 * time.Second}, {4 * time.Second},
    }
    for _, c := range candidates {
    c := c // capture
    t.Run(fmt.Sprintf("%v", c.dur), func(t *testing.T) {
    t.Parallel()
    time.Sleep(c.dur)
    })
    }
    }

    View Slide

  26. Parallelize Tests
    -To detect race condition-

    View Slide

  27. Parallelize tests (race condition)
    var cache = map[string]int{}
    func TestSimple(t *testing.T) {
    candidates := []struct {
    key string, value int
    }{ .. }
    for _, c := range candidates {
    c := c // capture
    t.Run(c.key, func(t *testing.T) {
    t.Parallel()
    // read and/or write something with cache variable.
    })
    }
    }

    View Slide

  28. regexp.Regexp

    View Slide

  29. regexp.Regexp
    • Implementation of regexp.Regexp
    • Safe for use by concurrent goroutines
    • Initialization cost performance is not good
    • Avoid initializing as locals in functions

    View Slide

  30. regexp.Regexp - Benchmark code
    func BenchmarkRegexpMustCompile1(b *testing.B) {
    b.ResetTimer()
    for i := 0; i < b.N; i++ {
    re := regexp.MustCompile("[a-z]{3}") // ❌
    _ = re.FindAllString(`Lorem ipsum dolor sit amet, consectetur..`)
    }
    }
    func BenchmarkRegexpMustCompile2(b *testing.B) {
    re := regexp.MustCompile("[a-z]{3}") // ⭕
    b.ResetTimer()
    for i := 0; i < b.N; i++ {
    _ = re.FindAllString(`Lorem ipsum dolor sit amet, consectetur..`)
    }
    }

    View Slide

  31. regexp.Regexp - Benchmark result
    • BenchmarkRegexpMustCompile1-16
    • 5000 385760 ns/op 100850 B/op 830 allocs/op
    • BenchmarkRegexpMustCompile2-16
    • 5000 367423 ns/op 59961 B/op 805 allocs/op
    Using Huge Data

    View Slide

  32. regexp.Regexp.Copy

    View Slide

  33. regexp.Regexp.Copy
    • Implementation of regexp.Regexp
    • Safe for use by concurrent goroutines
    • Using a sync.Mutex to protect a cache
    • Causes degraded performance using the same Regexp
    • Copy method is available for go1.6 or later

    View Slide

  34. regexp.Regexp.Copy - Benchmark code
    func BenchmarkParallelRegexpMustCompileCopy(b *testing.B) {
    re := regexp.MustCompile("[a-z]{3}")
    b.ResetTimer()
    b.RunParallel(func(pb *testing.PB) {
    // Copy Regexp
    // https://golang.org/src/regexp/all_test.go?s=20028:20077#L718
    re := re.Copy() // ❤
    for pb.Next() {
    _ = re.FindAllString(`Lorem ipsum dolor sit amet, consectetur..`)
    }
    }
    }

    View Slide

  35. regexp.Regexp.Copy - Benchmark result
    • BenchmarkParallelRegexpMustCompileNoCopy-16
    • 5000 375899 ns/op 99689 B/op 817 allocs/op
    • BenchmarkParallelRegexpMustCompileCopy-16
    • 30000 56602 ns/op 59976 B/op 805 allocs/op
    Using Huge Data and Parallal Benchmarking

    View Slide

  36. Summaries

    View Slide

  37. Summaries
    • Keep Go Proverbs of Rob Pike in your mind to write go code.
    • https://go-proverbs.github.io
    • Understand how to handle Constants.
    • Parallelism Testing and Benchmarking.
    • Not to put regexp on your code as possible.
    • Use strings package instead of it.
    • (And) Read Release Notes
    • https://golang.org/doc/go1.7

    View Slide

  38. Thank you
    Credit: NASA Earth Observatory/NOAA NGDC

    View Slide