Skip to content

Latest commit

 

History

History
106 lines (75 loc) · 3.65 KB

optimize.md

File metadata and controls

106 lines (75 loc) · 3.65 KB

Miki's Optimization Guide

3 Rules of Optimization

  1. Don't : You first need to have measurable performance goals ("as fast as you can't" is not an acceptable goal). If you hit these goals go do something with better business value.

  2. Don't ... yet : It's much easier and cheaper to fix the problem with hardware. Get a faster CPU, faster network ... Developer time & money are the most expensive resources in software development. Also note that optimized code is much harder to maintain.

  3. Profile before optimizing : Bottlenecks will surprise you. Don't guess where the code spends it's time, use a profiler and see.

See more here and here.

General

  1. Algorithms & Data structures Rule : They will usually give you much better performance than any other trick.

  2. Know thy Hardware : CPU affinity, CPU cache, memory, latency numbers .... For example: Cache-oblivious algorithms

  3. Include performance in your process : Design & code reviews, run & compare benchmarks on CI ...

Go Specific

  1. Memory Allocation : Avoid allocations as possible (see the design of io.Reader). Pre-allocate if you already know the size. Be careful of slices keep large amounts of memory (s := make([]int, 1000000)[:3])

  2. defer might slow you Down : However consider the advantages.

  3. strings are immutable : Use bytes.Buffer or strings.Builder

  4. Know when a goroutine is going to stop : Avoid goroutine leaks. Use context for cancellation/timeouts.

  5. Cgo calls are expensive : Group them together in one cgo call.

  6. Channel can be slower than sync.Mutex : However they are much easier to work with

  7. Interface calls are more expensive the struct calls : You can extract the value from the interface first. However it's less generic code.

  8. Use go run -gcflags=-m -l : You'll see what escapes to the heap.

Reading

{::comment}

Performance Mantras

By Craig Hanson and Pat Crain

  1. Don't do it : Can we avoid doing the calculation at all? For example: Do we need to parse the input or just pass it as-is?

  2. Do it, but don't do it again : Can we use memoization/caching? Parse objects once at the "edges" and use the parsed objects internally.

  3. Do it less : Do we need to run this every millisecond? Can every second work? Can we use only a subset of the data?

  4. Do it later : Can we make this API call async?

  5. Do it when they're not looking : Can we run the calculation in the background while doing another task?

  6. Do it concurrently : Will concurrency help here? Consider Amdhal's law.

  7. Do it cheaper : Can we use a map here instead of a slice? Research available algorithms and data structures and know their complexity. Test them on your data

{:/comment}