- Profile before optimizing: use JMH for microbenchmarks, async-profiler or JFR for production profiling.
- Use `StringBuilder` for string concatenation in loops — `+` creates new objects on each iteration.
- Use JMH (`@Benchmark`) for microbenchmarks — avoid premature optimization based on intuition, measure with JVM warm-up.
- Use `ArrayList` over `LinkedList` in almost all cases — cache locality dominates pointer chasing.
- Use `HashMap` initial capacity to avoid rehashing: `new HashMap<>(expectedSize * 4 / 3 + 1)`.
- Use `Stream.parallel()` only for CPU-heavy operations on large datasets — parallelism has overhead.
- Use primitive specializations (`IntStream`, `LongStream`) to avoid boxing in numeric streams.