• 不要省略 defer
      • 在大多数情况下 200ns 加速可以忽略不计
    • 总是关闭 http body defer r.Body.Close()
      • 除非你需要泄露 goroutine
    • 过滤但不分配新内存
    • time.Time 有指针字段 time.Location 并且这对 go GC 不好
      • 只有使用了大量的 time.Time 才(对性能)有意义,否则用 timestamp 代替
    • regexp.MustCompileregexp.Compile 更好
      • 在大多数情况下,你的正则表达式是不可变的,所以你最好在 func init 中初始化它
    • 请勿在你的热点代码中过度使用 fmt.Sprintf. 由于维护接口的缓冲池和动态调度,它是很昂贵的。
      • 如果你正在使用 fmt.Sprintf("%s%s", var1, var2), 考虑使用简单的字符串连接。
      • 如果你正在使用 fmt.Sprintf("%x", var), 考虑使用 hex.EncodeToString or
    • 如果你不需要用它,可以考虑丢弃它,例如io.Copy(ioutil.Discard, resp.Body)
      • HTTP 客户端的传输不会重用连接,直到body被读完和关闭。
    1. res, _ := client.Do(req)
    2. io.Copy(ioutil.Discard, res.Body)
    • 不要在循环中使用 defer,否则会导致内存泄露
      • 因为这些 defer 会不断地填满你的栈(内存)
    • 不要忘记停止 ticker, 除非你需要泄露 channel
    • 用自定义的 marshaler 去加速 marshaler 过程
      • 但是在使用它之前要进行定制!例如:
    1. func (entry Entry) MarshalJSON() ([]byte, error) {
    2. buffer := bytes.NewBufferString("{")
    3. first := true
    4. for key, value := range entry {
    5. jsonValue, err := json.Marshal(value)
    6. if err != nil {
    7. return nil, err
    8. }
    9. if !first {
    10. }
    11. first = false
    12. }
    13. buffer.WriteString("}")
    14. return buffer.Bytes(), nil
    15. }
    • 对于最快的原子交换,你可以使用这个 m := (*map[int]int)(atomic.LoadPointer(&ptr))
      • 减少系统调用次数
      • 重用 map 内存 (但是也要注意 m 的回收)
    1. for k := range m {
    2. delete(m, k)
    • 分配新的