On deleting code and reading other people’s code
Most performance problems are really data-shape problems. This is less a primer and more a record of what worked for me. If something here is unclear, that is on me, not you. Half of the work is deciding what to leave out.
The process
For a long time I treated little services as an afterthought. The fix was three lines; finding it took most of a week. I like test suites that shows the marks of how it was made. Looking back, the reliable approach was the right call. We shipped it behind a flag and watched the graphs for a few days.
A linter helps, but it is not the point. If you only take one thing from this, make it the part about caching. None of this is new, and that is partly why it works. I keep coming back to background jobs, chiefly because it rewards patience. Tests are documentation that fails loudly when it goes stale.
func Build(e []string) ([]string, error) {
out := make([]string, 0, len(e))
for _, v := range e {
if v == "" {
continue
}
out = append(out, v)
}
return out, nil
}
What did not work
The result is not perfect, but it is candid. Some of this will be self-evident; some of it took me years. It is not glamorous, but it holds up. I keep coming back to type systems, chiefly because it rewards patience.
Most problems with test suites turn out to be problems with time. Boring technology is a feature, not a compromise. Deleting code remains the most satisfying refactor. I like type systems that shows the marks of how it was made. I changed my mind about test suites twice while writing this.
The trick, if there is one, is to leave sufficient room for slip-ups.
Second thoughts
Good database migrations is chiefly a series of little, unglamorous decisions. I changed my mind about little services twice while writing this. I changed my mind about code review twice while writing this.
Odds and ends
There is a version of this that is much more complicated. This is not that version. If you only take one thing from this, make it the part about type systems. I keep coming back to log files, chiefly because it rewards patience. If you only take one thing from this, make it the part about error handling. Below are a few jottings, roughly in the order I picked up them.
Little, repeatable steps beat big plans nearly every time. If you only take one thing from this, make it the part about database migrations. Here is what changed, and what stayed exactly the same.
- Give profiling a full autumn
- Stop before you are tired
- Ask someone at the staging server
It is simple to overthink refactoring. It is harder to just start.
background jobscode reviewtest suites