Learn Python with Talk Python's 270 hours of courses

Python Perf: Specializing, Adaptive Interpreter

Episode #381, published Fri, Sep 16, 2022, recorded Thu, Sep 15, 2022

We are on the edge of a major jump in Python performance. With the work done by the Faster CPython team and Python 3.11 due out in around a month, your existing Python code might see an increase of well over 25% in speed with no changes. One of the main reasons is its new specializing, adaptive interpreter.

This episode is about that new feature and a great tool called Specialist which lets you visualize how Python is speeding up your code and where it can't unless you make minor changes. Its creator, Brandt Bucher is here to tell us all about.

Watch this episode on YouTube
Play on YouTube
Watch the live stream version

Episode Deep Dive

Guest Introduction and Background

Brandt Bucher is a Python core developer who joined the Faster CPython team at Microsoft. He studied computer engineering at UC Irvine, discovering his love for Python during a senior design project. Over time, he became a Python triager, then a core developer, and now focuses on performance improvements within CPython. In this episode, Brandt shares how his passion for open-source contributions and his background in both software and hardware led him to develop a tool called Specialist, which visualizes Python’s new adaptive interpreter optimizations introduced in Python 3.11.

What to Know If You're New to Python

If you're newer to Python and this performance discussion sounds advanced, don’t worry. You just need to be aware of a few basic concepts before diving in:

  • Python’s language and runtime are extremely dynamic—variables (their types and locations) can change as the program runs.
  • Python 3.11 introduces an optimization layer in CPython called the specializing adaptive interpreter (PEP 659).
  • Tools like Specialist help show how Python’s optimizations apply in your code.
  • Some math details might get specialized (optimized), but only if your code and data types line up in a way Python expects (like float + float, not float + int).

Key Points and Takeaways

  1. Why Python 3.11 is Significantly Faster
    Python 3.11 brings notable performance improvements—often quoted as a 25% speed boost or more for everyday code. Much of this jump is due to the specializing adaptive interpreter, which replaces general-purpose bytecode instructions with specialized ones at runtime.

  2. The Specializing Adaptive Interpreter (PEP 659)
    This interpreter detects the most common code paths and swaps out general bytecode instructions for specialized ones (e.g., BINARY_ADD becomes BINARY_ADD_INT if it consistently sees integers). It then adapts or “falls back” if those assumptions become invalid (e.g., you switch from integer to string addition).

  3. Adaptive vs. Specialized Instructions
    In Python 3.11, bytecode instructions can be in an “adaptive” state while the interpreter observes real-world data. Once stable patterns emerge (e.g., always floats), the adaptive instructions switch to specialized ones (e.g., float-specific math). If the pattern changes, the interpreter falls back automatically.

  4. Transparent Speedups with No Code Changes
    One of the best features of the new adaptive interpreter is that most Python users do not need to modify their code to benefit. Simply upgrading to Python 3.11 can result in impressive speed improvements, especially for tight computational loops or repeated function calls.

  5. Specialist: Visualizing Where Python Optimizes
    Brandt created Specialist to highlight where code is specialized (in green) or not specialized (in red or yellow). By running your code under Specialist, you get an annotated view showing which parts of your program Python speeds up and which parts remain generic.

  6. Minor Tweaks for Major Gains
    Brandt shared examples like changing 32 to 32.0 in a Fahrenheit-to-Celsius function. This small change—ensuring both operands are floats—increases the likelihood Python will specialize the math operations. Reordering or combining certain operations (e.g., (5/9)*x vs. 5*(x/9)) might also trigger compile-time optimizations.

  7. Falling Back from Specialized Modes
    The interpreter’s fallback mechanism ensures correctness remains paramount. If Python sees unexpected types (e.g., switching from integer to string addition), it discards the specialized instructions and reverts to the slower, more general approach until it has stable assumptions again.

    • Tools and Concepts:
      • Fallback to “adaptive” or “generic” opcodes
  8. Collaboration with Other Python Teams
    The Faster CPython team regularly collaborates with other performance-focused groups, such as the Cinder folks at Meta (Facebook). While not all custom implementations (like JITs in Cinder) are upstreamed, knowledge sharing accelerates CPython’s performance improvements for everyone.

  9. Potential Future Directions (3.12 and Beyond)
    The team is exploring more specializations and possibly a JIT, but these efforts likely won’t land in 3.12. However, the adaptive interpreter infrastructure lays the groundwork for more advanced optimizations—meaning Python’s speed story will keep evolving.

  10. Practical Advice on Assessing Performance
    Brandt recommends upgrading first, seeing if your code gets noticeably faster, and only then using Specialist to find any missed optimizations in truly performance-critical code. For large or production applications, building CPython with profiling stats (--with-pystats) can reveal deeper insights without exposing proprietary code.

Interesting Quotes and Stories

  • Brandt on contributing to CPython: “I’d wake up, go to a coffee shop, and for a half hour just look at newly opened issues from first-time contributors … so they wouldn’t have the same slow experience I had.”
  • On surprising small tweaks: “Just adding a decimal to an integer changed the math to float-plus-float, letting the interpreter actually speed up your code.”

Key Definitions and Terms

  • Bytecode: A lower-level, platform-independent representation of your Python code, executed by the CPython virtual machine.
  • Adaptive Instruction: A bytecode placeholder that observes the runtime types and patterns before deciding which specialized approach to use.
  • Specialized Instruction: A faster bytecode operation optimized for specific data types (e.g., ADD_FLOAT, LOAD_SLOT).
  • Fallback: The mechanism by which Python discards specialized instructions if runtime conditions no longer match the initial assumptions.
  • PEP 659: A Python Enhancement Proposal introducing the specialized adaptive interpreter in Python 3.11.

Learning Resources

If you want to deepen your Python foundations or explore Python 3.11 features in detail, here are some excellent courses from Talk Python Training:

Overall Takeaway

Python 3.11 ushers in a transformative jump in performance by integrating the specializing adaptive interpreter. Brandt Bucher’s work on both CPython’s speedups and his Specialist tool showcases how seemingly small adjustments—like enforcing consistent data types—can significantly impact execution time. By upgrading to Python 3.11, most developers will see notable speed boosts with no code changes. For those wanting to push Python’s performance boundaries further, specialized visualization tools and deeper runtime introspection are now available. The overarching message is clear: Python is growing ever faster and more powerful, and the best is yet to come.

Links from the show

Brandt Bucher: github.com
Specialist package: github.com
Faster CPython: github.com
Faster CPython Ideas: github.com
pymtl package: pypi.org
PeachPy: github.com
Watch this episode on YouTube: youtube.com
Episode transcripts: talkpython.fm

--- Stay in touch with us ---
Subscribe to Talk Python on YouTube: youtube.com
Talk Python on Bluesky: @talkpython.fm at bsky.app
Talk Python on Mastodon: talkpython
Michael on Bluesky: @mkennedy.codes at bsky.app
Michael on Mastodon: mkennedy

Talk Python's Mastodon Michael Kennedy's Mastodon