Git Product home page Git Product logo

go-advices's Introduction

Go-advices

Code

  • go fmt your code, make everyone happier
  • multiple if statements can be collapsed into switch
  • use chan struct{} to pass signal
    • chan bool makes it less clear, btw struct{} is more optimal
  • prefer 30 * time.Second instead of time.Duration(30) * time.Second
  • always wrap for-select idiom to a function
  • group const declarations by type and var by logic and/or type
  • every blocking or IO function call should be cancelable or at least timeoutable
  • implement Stringer interface for integers const values
  • check your defer's error
    defer func() {
        err := ocp.Close()
        if err != nil {
            rerr = err
        }
    }()
  • don't use checkErr function which panics or does os.Exit
  • don't use alias for enums 'cause this breaks type safety
    package main
    type Status = int
    type Format = int // remove `=` to have type safety
    
    const A Status = 1
    const B Format = 1
    
    func main() {
      println(A == B)
    }
  • if you're going to omit returning params, do it explicitly
    • so prefer this _ = f() to this f()
  • we've a short form for slice initialization a := []T{}

CI

Concurrency

  • best candidate to make something once in a thread-safe way is sync.Once
    • don't use flags, mutexes, channels or atomics
  • to block forever use select{}, omit channels, waiting for a signal

Performance

  • do not omit defer
    • 200ns speedup is negligible in most cases
  • always close http body aka defer r.Body.Close()
    • unless you need leaked goroutine
  • filtering without allocating
      b := a[:0]
      for _, x := range a {
      	if f(x) {
      	    b = append(b, x)
      	}
      }
  • time.Time has pointer field time.Location and this is bad for go GC
    • it's relevant only for big number of time.Time, use timestamp instead
  • prefer regexp.MustCompile instead of regexp.Compile
    • in most cases your regex is immutable, so init it in func init
  • do not overuse fmt.Sprintf in your hot path. It is costly due to maintaining the buffer pool and dynamic dispatches for interfaces.
    • if you are doing fmt.Sprintf("%s%s", var1, var2), consider simple string concatenation.
    • if you are doing fmt.Sprintf("%x", var), consider using hex.EncodeToString or strconv.FormatInt(var, 16)
  • always discard body e.g. io.Copy(ioutil.Discard, resp.Body) if you don't use it
    • HTTP client's Transport will not reuse connections unless the body is read to completion and closed
      res, _ := client.Do(req)
      io.Copy(ioutil.Discard, res.Body)
      defer res.Body.Close()
  • don't use defer in a loop or you'll get a small memory leak
    • 'cause defers will grow your stack without the reason
  • don't forget to stop ticker, unless you need leaked channel
    ticker := time.NewTicker(1 * time.Second)
    defer ticker.Stop()

Build

  • strip your binaries with this command go build -ldflags="-s -w" ...
  • easy way to split test into different builds
    • use // +build integration and run them with go test -v --tags integration .

Testing

  • go test -short allows to reduce set of tests to be runned
    func TestSomething(t *testing.T) {
      if testing.Short() {
        t.Skip("skipping test in short mode.")
      }
    }
  • skip test deppending on architecture
    if runtime.GOARM == "arm" {
      t.Skip("this doesn't work under ARM")
    }
  • prefer package_test name for tests, rather than package
  • for fast benchmark comparison we've a benchcmp tool

Tools

  • quick replace gofmt -w -l -r "panic(err) -> log.Error(err)" .
  • go list allows to find all direct and transitive dependencies
    • go list -f '{{ .Imports }}' package
    • go list -f '{{ .Deps }}' package

Misc

  • dump goroutines https://stackoverflow.com/a/27398062/433041
      go func() {
        sigs := make(chan os.Signal, 1)
        signal.Notify(sigs, syscall.SIGQUIT)
        buf := make([]byte, 1<<20)
        for {
            <-sigs
            stacklen := runtime.Stack(buf, true)
            log.Printf("=== received SIGQUIT ===\n*** goroutine dump...\n%s\n*** end\n", buf[:stacklen])
        }
    }()
  • check interface implementation during compilation
      var _ io.Reader = (*MyFastReader)(nil)
  • if a param of len is nil then it's zero
  • anonymous structs are cool
    var hits struct {
      sync.Mutex
      n int
    }
    hits.Lock()
    hits.n++
    hits.Unlock()
  • httputil.DumpRequest is very useful thing, don't create your own

go-advices's People

Contributors

cristaloleg avatar agnivade avatar bradleyjkemp avatar gregory-m avatar detailyang avatar tannineo avatar

Watchers

James Cloos avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.