# Go Data Structures Quick Reference

## Complexity Cheat Sheet

| Operation | slice | map | sync.Map | heap (container/heap) |
|-----------|-------|-----|----------|-----------------------|
| Lookup by index | O(1) | - | - | - |
| Lookup by key | O(n) | O(1) avg | O(1) avg | - |
| Append/Push | O(1)* | O(1)* | O(1) | O(log n) |
| Pop front | O(n) | - | - | O(log n) |
| Pop back | O(1) | - | - | - |
| Delete by key | O(n) | O(1) | O(1) | O(n) |
| Iterate | O(n) | O(n) | O(n) | O(n) |
| Sorted iterate | O(n log n) | O(n log n) | O(n log n) | O(n log n) |

*amortized; may trigger grow/rehash

## When to use what

| Need | Use | Avoid |
|------|-----|-------|
| Ordered collection | `[]T` | `map` (no order) |
| Fast lookup by key | `map[K]V` | `[]T` linear scan |
| Set membership | `map[T]struct{}` | `[]T` contains check |
| Concurrent reads, rare writes | `sync.Map` | `map` + `sync.Mutex` |
| Concurrent writes | Sharded `map` + `sync.RWMutex` | `sync.Map` |
| Priority queue | `container/heap` | Sorted slice |
| FIFO queue | Slice (append + slice) or ring buffer | `list.List` (alloc per node) |
| LRU cache | `map` + `container/list` | Custom linked list |
| Stack | Slice (append/pop) | `container/list` |

## Allocation Costs

| Pattern | Allocs | Fix |
|---------|--------|-----|
| `append` without cap | O(log n) grows | `make([]T, 0, n)` |
| `map` without size hint | Rehashes | `make(map[K]V, n)` |
| `fmt.Sprintf` | 1+ (reflect) | `strconv` + `strings.Builder` |
| `string([]byte)` | 1 copy | Work in `[]byte` or `unsafe` |
| `interface{}` boxing | 1 per box (~11% CPU overhead) | Concrete types / generics |
| `regexp.Compile` | Many | Compile once at package level |
| Unbuffered file writes | 1 syscall per write | `bufio.Writer` (62× faster) |
| Unbatched I/O ops | N calls for N items | Batch (12× for file I/O) |
| Mutex for simple counter | 110.7 ns/op | `atomic.Int64` (80.4 ns/op, 27% faster) |

## Benchmark Reference Numbers

| Pattern | Metric | Impact |
|---------|--------|--------|
| Atomic vs Mutex increment | 80.4 vs 110.7 ns/op | **27% faster** |
| Batched file I/O | 12.7ms → 994µs/op | **12× throughput** |
| Batched crypto (SHA256) | 1.23ms → 675µs/op | **~2× faster** |
| Buffered writes (bufio) | 23.6ms → 380µs/op | **62× faster** |
| Pre-allocated slices | dynamic grow | **4× faster** |
| sync.Pool object reuse | 864 → 42 ns/op | **20× throughput** |
| Worker pool vs unbounded | bounded goroutines | **28% faster** |
| Interface boxing (large) | baseline | **~11% CPU overhead** |

## Go Version Performance Notes

| Version | Impact |
|---------|--------|
| Go 1.24 | Swiss Tables hash map — faster map insert/lookup/delete |
| Go 1.25 | TLS 1.3 fast path (~58% handshake improvement) |
| Go 1.26 | Small alloc specialization (sub-32-byte), `io.ReadAll` ~2× throughput, RSA-4096 keygen ~3× faster |
