Slide 1

Slide 1 text

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

Slide 2

Slide 2 text

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

Slide 3

Slide 3 text

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

Slide 4

Slide 4 text

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

Slide 5

Slide 5 text

Go Proverbs

Slide 6

Slide 6 text

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

Slide 7

Slide 7 text

Go Proverbs - Rob Pike - Gopherfest

Slide 8

Slide 8 text

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

Slide 9

Slide 9 text

Constants

Slide 10

Slide 10 text

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.

Slide 11

Slide 11 text

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) } }

Slide 12

Slide 12 text

Constants w/ iota

Slide 13

Slide 13 text

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

Slide 14

Slide 14 text

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<

Slide 15

Slide 15 text

Constants w/ type

Slide 16

Slide 16 text

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

Slide 17

Slide 17 text

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() { .. }

Slide 18

Slide 18 text

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

Slide 19

Slide 19 text

Testing

Slide 20

Slide 20 text

• 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

Slide 21

Slide 21 text

Table-driven tests

Slide 22

Slide 22 text

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) } } }

Slide 23

Slide 23 text

Parallelize Tests

Slide 24

Slide 24 text

Parallelize Tests -To save your time-

Slide 25

Slide 25 text

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) }) } }

Slide 26

Slide 26 text

Parallelize Tests -To detect race condition-

Slide 27

Slide 27 text

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. }) } }

Slide 28

Slide 28 text

regexp.Regexp

Slide 29

Slide 29 text

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

Slide 30

Slide 30 text

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..`) } }

Slide 31

Slide 31 text

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

Slide 32

Slide 32 text

regexp.Regexp.Copy

Slide 33

Slide 33 text

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

Slide 34

Slide 34 text

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..`) } } }

Slide 35

Slide 35 text

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

Slide 36

Slide 36 text

Summaries

Slide 37

Slide 37 text

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

Slide 38

Slide 38 text

Thank you Credit: NASA Earth Observatory/NOAA NGDC