Performance
-
Stack vs heap: what escape analysis taught me
Go's escape analysis decides where your variables live, and reading its output changed how I write performance-sensitive code
-
CPU caches explained through a slow hash table
A hash table that benchmarked beautifully in isolation was five times slower under realistic load, and L2 cache misses explained why
-
The branch predictor ate my microbenchmark
I was sure one version of a hot loop was faster; I was wrong; it was the CPU making me look smart
-
TIL: perf-map-agent for JVM flamegraphs
Attaching perf to a JVM produces garbage unless you tell perf where the JIT-compiled symbols are.
-
Atomic ordering made sense after I drew it on paper
Acquire, release, relaxed, sequential consistency — I finally have an intuition for when to use which
-
TIL: Go pprof labels for attributing CPU time
pprof.Labels lets you tag goroutines and filter flamegraphs by tag.
-
The GC knob that actually helped
GOMEMLIMIT is the Go runtime environment variable I wish I'd known about a year earlier
-
Trait objects vs generics: when I finally picked a side
After waffling for months, I have a rule for when to use dyn Trait and when to use impl Trait, and it holds up
-
Benchmarking gotchas I learned the hard way
A collection of ways I made Go benchmarks lie to me, including the compiler optimizations I didn't know existed
-
TIL: temp_buffers is a thing and default is tiny
When your query spills to disk, it's using temp_buffers. The default is 8MB, which is small.
-
TIL: EXPLAIN (ANALYZE, BUFFERS) shows cache hit ratio
The buffers flag tells you how much of your query was served from cache vs disk.
-
When interfaces in Go bite you at the allocation level
Converting a concrete type to an interface is not free, and in hot paths it can account for a startling share of GC pressure
-
The pprof graph that taught me to read assembly
A CPU profile pointed at a line with a simple map lookup, and pprof's disasm view sent me down a real rabbit hole
-
sync.Pool is not a memory pool
A long rant about what sync.Pool actually guarantees, when it helps, and when it just gives you the illusion of helping
-
Reading the Go scheduler traces for the first time
An evening with GODEBUG=schedtrace=1000 taught me more about what my service was actually doing than a month of metrics