Speaker Notes

Why performant code matters (but gets widely ignored), with Casey Muratori

Software performance requires measuring against hardware theoretical maximums, avoiding serial dependencies, and understanding CPU execution rather than relying on profiling or dogmatic coding rules.

The Pragmatic Engineer · 1:53:59 · YouTube ↗

Podcast interview · 1 host + guest  Intermediate · history, strategy, and performance concepts

Highlights

11 clips · 18 min of 114 min
    • Early Windows versions lacked the CPU pixel-filling speed needed for fast-paced games like Doom.
    • Microsoft engineer Chris Hecker created WinG as a covert skunkworks project to enable fast screen blits.
    • This unauthorized graphics library served as the direct technical and institutional ancestor to DirectX.
    • A 300-millisecond response budget is an eternity in modern computing given fast network ping times.
    • Many enterprise applications routinely take seconds to perform simple tasks due to systemic underperformance.
    • Running a profiler and tweaking code based on arbitrary statistics only traps developers in local performance minima.
    • True optimization requires calculating the hardware's theoretical maximum and measuring the delta against it.
    • Calculate the theoretical maximum performance of the underlying hardware first.
    • Measure the delta between the theoretical peak and your actual achievement.
    • Blindly tweaking code and measuring stats only traps you in local minimas.
    • High-level programming languages only represent input to the compiler and hide what the CPU actually executes.
    • Reading assembly language allows engineers to instantly verify whether the compiler generates the expected machine instructions.
    • High-level languages only show input to the compiler, hiding what the CPU actually executes.
    • Assembly output immediately reveals if the machine is being asked to do what you intend.
    • Knowing assembly unlocks the ability to read and interpret CPU architecture diagrams.
    • Software performance is generally dictated by the length of its longest serial dependency chain.
    • Code that sequentially waits for network requests cannot be multi-threaded or parallelized.
    • Architectural flaws like serial chains cannot be fixed later by standard hotspot tuning.
    • A simple operation like addition takes roughly a hundred more CPU instructions in Python than in C.
    • High amplification factors instantly kill performance when processing large datasets.
    • Interpreted languages necessitate leaning on pre-compiled libraries written in lower-level languages.
    • CPUs can be understood conceptually through data movement, instruction flow, and execution scheduling.
    • Data layout and access patterns often matter far more than hunting for code hotspots.
    • Knowing basic CPU mechanics builds fundamental software craftsmanship and better architectural intuition.
    • The primary performance cost of strict polymorphism isn't the virtual call itself.
    • Rigid design rules prevent the compiler from performing critical optimizations like inlining and vectorization.
    • Compilers can heroicly optimize messy static code, but runtime-unknown type substitutions completely block them.
    • Virtual function calls themselves are not the primary performance bottleneck.
    • The real cost is that unknown runtime types block the compiler from optimizing and vectorizing code.
    • Severe performance degradation occurs in production when compilers cannot inline or optimize.
    • Development should rarely be strictly driven by tests by default across all projects.
    • Evaluate testing strategies based on total engineering time saved versus maintenance and rigidity costs.
    • Different codebases warrant drastically different levels of test coverage based on intelligent engineering trade-offs.
    • Much received programming wisdom lacks empirical testing or tangible proof.
    • Great engineers focus on what actually works and can be measured in practice.
    • Blindly following popular coding practices without testing harms codebase quality.
    • Academic papers provide historical context and expose developers to entirely new techniques.
    • Searching Google Scholar and crawling references yields better insights than standard books.
    • Deep technical reading is a powerful tool for mastering unfamiliar programming domains.

Questions this video answers

11 · every answer cites the moment it was said
01 How did Microsoft Windows become a gaming platform? 2 sources · 8:07

Early versions of Windows lacked the fast CPU pixel-filling and display negotiation needed for games, so developers like Chris Hecker created a skunkworks library called WinG to enable fast screen blitting. This unapproved graphics add-on served as the direct institutional and technical precursor to DirectX, which eventually established Windows as a dominant gaming platform. Although management volatility temporarily disrupted the project, it successfully proved that Windows could handle high-performance graphics.

02 Why do most engineering teams and developers ignore software performance? 2 sources · 17:19

Developers often overlook performance because enterprise software purchasers care more about compliance and cost than speed, and monopoly network effects make responsiveness secondary to user acquisition. Furthermore, a general lack of awareness regarding hardware limits leads to poor benchmarking and bloated software budgets. However, recent trends show that startups using performance-based pitches are starting to gain traction against sluggish incumbents.

03 How should I actually approach optimizing software performance? 2 sources · 24:01

True optimization requires identifying the theoretical peak capabilities of the underlying hardware and measuring the performance delta against your current implementation. Relying solely on a profiler to find big bottlenecks only traps you in local minima without knowing what the machine is truly capable of achieving. Calculating theoretical maximums also helps engineers discover hardware anomalies and continuously learn about modern CPU architectures.

04 Why should I learn assembly language if I never write it? 2 sources · 27:37

Reading assembly is essential because it reveals the exact instructions the CPU is being asked to execute, unlike high-level languages which only show input to a compiler. It is surprisingly simple, requiring you to learn only a small subset of instructions that compilers actually output. Once you know it, you can read hardware architecture diagrams and understand CPU performance directly.

05 What is a false serial dependency chain and how does it hurt performance? 2 sources · 34:21

A serial dependency chain occurs when operations must happen in a specific order, such as waiting for a network request to finish before doing the next calculation. Because performance is determined by the longest un-parallelizable chain, this architectural pattern cannot be easily fixed by localized hotspot optimization. Avoiding it requires designing architectures that batch requests upfront and only chain when strictly necessary.

06 What basic CPU mechanics do I need to understand for better software design? 2 sources · 51:00

You should understand how data moves through load store units and cache hierarchies like L1, L2, and L3 caches to optimize data access patterns. It is also helpful to conceptualize instruction flow, branch misprediction, and execution unit scheduling throughput. Knowing these components allows you to make informed architectural choices that keep your software performant without needing to be a hyper-optimizer.

07 How did the rise of licensable game engines change the indie and AAA games market? 3 sources · 1:06:38

Licensable engines eliminated the massive technical risk of building engines from scratch, allowing many more creators to publish games. However, this drastically flooded storefronts like Steam, making organic discovery nearly impossible and turning marketing and distribution into the true differentiators. Additionally, games now compete not just against new releases, but against timeless older titles and always-on live services.

08 Why do clean code rules like excessive small functions and polymorphism degrade performance? 3 sources · 1:18:34

Rules that mandate polymorphism and tiny functions fundamentally block compilers from performing crucial optimizations like inlining and code collapsing. When a compiler cannot determine runtime behavior or potential class substitutions, it cannot optimize the execution path. The actual performance cost stems from the loss of compiler optimization capabilities rather than the virtual function call itself.

09 What is a pragmatic approach to testing and test-driven development? 2 sources · 1:23:02

Development should not be blindly driven by tests by default, as rigid testing requirements can make codebases harder to change and maintain. Instead, engineers should pragmatically evaluate whether the cost of creating and maintaining tests is outweighed by the bugs they prevent.

10 How does developer autonomy influence the experience of using AI tools? 2 sources · 1:47:12

Developers with a high degree of autonomy view AI tools positively, using them optionally to eliminate tedious tasks. Conversely, engineers who lack control and are mandated by management to use AI under strict output pressure often experience burnout and fear automation of their roles.

11 Why does reading technical papers build deep expertise? 2 sources · 1:50:55

Reading technical papers allows developers to uncover historical context, trace reference chains, and discover entirely new programming techniques. This deep dive approach helps programmers expand their domain knowledge far beyond standard books or blogs.

Section-by-section summary

21 parts

Early exposure to computers through Digital Equipment Corporation

Casey Muratori learned to program at age seven because his father worked as a programmer at DEC, providing rare home computer access in the early 1980s. This early foundation set the stage for his eventual entry into the game industry through connections made at Microsoft.

Sneaking WinG into Windows to enable PC gaming

Early Windows versions lacked the graphics performance required for action games, prompting Microsoft engineer Chris Hecker to secretly develop the WinG graphics library. This skunkworks project bypassed standard OS limitations and laid the technical and institutional groundwork for DirectX.

Building tools and independent game development

After his Microsoft internship, Muratori worked on titles like Dungeon Siege and created a popular character animation system at Rad Game Tools that remains in use today. He later operated independently and contributed performance programming to projects like The Witness.

The root causes of industry-wide performance neglect

Software performance is frequently ignored due to enterprise purchasing dynamics, software monopolies where performance cannot overcome network effects, and a general lack of awareness regarding hardware limits. However, recent performance-focused alternatives are beginning to challenge entrenched slow incumbents.

Optimization requires measuring against theoretical hardware maximums

Traditional profiling merely finds local minima by measuring arbitrary statistics after making minor tweaks. True optimization starts by calculating the theoretical peak performance of the hardware and shrinking the gap between that maximum and the actual implementation.

Read assembly to see CPU execution

High-level languages obscure what instructions are actually sent to the processor. Because compilers only output a small subset of instructions, learning basic assembly is straightforward and gives engineers precise visibility into machine operations.

Avoid false serial dependency chains

While delaying optimization is viable for isolated hotspots, poor upfront architecture like serial dependency chains cannot be easily fixed later. If an entire system is architected to wait sequentially on network requests, no amount of downstream hotspot tuning will save its performance.

Language rewrites expose architectural limits

Companies frequently rewrite massive backend systems from Python to Rust or Go because initial architectural choices hit severe scaling walls. Public engineering blog posts often spin these rewrites positively to mask original architectural oversights.

Recognize orders of magnitude in performance

Writing performant software does not require hyper-optimization, but rather an awareness of hardware capabilities and language overheads. Understanding that a Python operation takes orders of magnitude more instructions than C empowers engineers to make informed architectural trade-offs.

Understand basic CPU mechanics for better design

Knowing how CPUs handle data caches, instruction flow, and execution scheduling helps developers structure data access patterns correctly. This foundational knowledge transforms software engineering from guesswork into a predictable, rigorous discipline.

Early game development was defined by massive technical risks

Historically, game studios had to build custom rendering engines and tools from scratch for every title, introducing severe engine risk. Teams faced immense uncertainty because they couldn't run the game or build final levels until the core technology matured.

Licensable engines democratized creation but flooded the market

The rise of accessible off-the-shelf engines eliminated technical barriers and engine risk for indie developers. However, it exponentially increased market saturation, making discoverability and marketing far more critical than raw game quality alone.

Modern games compete against live services and older titles

Current games face fierce zero-sum competition not just from new releases, but from entrenched live-service giants and visually timeless older titles. Because consumer graphical standards have plateaued, older games remain viable entertainment options that capture player time.

AAA sequels like GTA 6 function as platform replacements

Blockbuster sequels with massive development cycles are not just standalone games, but massive live-service platform replacements. Publishers spend years ensuring a smooth rollout to avoid cannibalizing multi-billion-dollar ongoing revenue streams from previous titles.

Clean code rules block compiler optimizations and degrade performance

Strict design rules like maximizing small virtual functions and forcing polymorphism prevent modern compilers from performing vital optimizations like inlining and vectorization. The real performance penalty comes from blinding the compiler rather than the overhead of virtual dispatch.

Testing strategies should be pragmatic rather than dogmatic

Test-driven development should not be treated as a default rule, but evaluated through a cost-benefit lens of maintenance effort versus bugs caught. Engineers should make intentional testing decisions tailored to the specific needs of each project.

Good code aligns with machine execution

High-quality code is straightforward, maps closely to what the computer actually needs to do, and avoids over-engineered abstractions. Well-architected code naturally runs fast without sacrificing readability or maintainability.

Software engineering resembles specialized sports roles

Great software engineers come in vastly different archetypes, much like players on a baseball team. Building an effective team requires matching individuals to specific roles rather than looking for a generic one-size-fits-all profile.

Preserving the traditional craft without AI

Choosing not to use AI for personal software projects is often a philosophical decision about enjoying the craft of programming. Human-authored software maintains a tradition of handcrafting similar to artisans in other trades.

Autonomy shapes developer burnout from AI

Developers who have high autonomy view AI as an optional tool to eliminate tedious tasks, resulting in a positive experience. Conversely, those facing strict corporate AI mandates experience fatigue and anxiety over job security.

Reading technical papers builds deep expertise

Developers can gain immense knowledge and discover novel techniques by searching Google Scholar and reading academic papers. Crawling research references uncovers historical context and practical solutions that standard programming books miss.

0:00 / 1:53:59
k play/pause · f fullscreen · m mute
n next · p previous clip · t highlights/full
< > slower/faster · / search what was said
  • WinG3× · first 8:37

    An early skunkworks add-on library for Microsoft Windows that enabled fast screen blitting and paved the way for DirectX.

  • Assembly language19× · first 0:14

    Low-level machine instructions used to inspect exact CPU execution rather than relying on compiler output.

  • Serial dependency chain2× · first 34:24

    A sequence of dependent operations that must execute in order and cannot be parallelized, limiting performance.

  • Test-driven development2× · first 1:21:44

    A software development process where tests are written before the business logic.

  • SIMD1× · first 1:19:50

    Single Instruction Multiple Data, a computer architecture technique used by compilers for vectorization.