The performance loop—A practical guide to profiling and benchmarking - Daniel Marbach - NDC Oslo

Learn practical techniques for profiling and benchmarking applications, from setting up isolated environments to measuring CPU/memory performance and preventing regressions.

Key takeaways
  • Start with benchmarking memory allocations before CPU optimizations - memory issues often have bigger impact and are easier to optimize

  • Create isolated benchmark environments by copying relevant code into a dedicated repository to avoid complexity and side effects

  • Use benchmark.NET framework to handle the complexities of reliable benchmarking rather than building custom solutions

  • Take both memory and CPU profiles/snapshots before and after optimizations to verify improvements

  • Focus optimization efforts on the hot path and most frequently executed code paths first

  • Make explicit tradeoffs - don’t try to optimize everything, focus on areas where you have domain knowledge and that provide the most value

  • Document performance-related decisions and learnings to share knowledge with the team

  • Add regression tests for critical performance benchmarks to CI/CD to prevent regressions

  • Run benchmarks in release mode with proper warm-up iterations to get reliable results

  • Small iterative 1% improvements compound over time into significant performance gains when applied consistently

  • Remember that benchmarks should measure one specific thing, like unit tests, but provide statistical results rather than pass/fail

  • Profile both happy path and exception cases, as error handling can have significant performance impact at scale

  • Consider the environmental impact - more efficient code means less energy consumption in production