Contents

Speed up Python code with Pyjion

Microsoft’s Pyjion compiler for Python reaches stable version 1.0

What is Pyjion

The most common way to speed up your Python code is to use CPython, the official Python interpreter. It compiles code into an intermediary language called bytecode and evaluates this code whenever your code is executed. This allows lots of flexibility, but has a downside. Simple calculations where CPUs are very efficient, like arithmetic of integers and floating point numbers are significantly slower in CPython than other interpreters.

In practice, Python developers adopt tools like Cython to make numerical operations more efficient by compiling code ahead of time, using C extensions. This is an effective solution for performance, but isn’t ideal for rapid iteration or experimentation, especially in Jupyter notebooks.

This is where Pyjion comes to help. Pyjion is a Python 3.10 package that analyses Python code and optimizes it on the fly, using a JIT, or “Just-in-Time” compiler. It can be used in a program simply by importing the Pyjion library and enabling it. Everything that runs after that statement is JIT-compiled.

How to pronounce

“Pyjion” is pronounced like the word “pigeon”. @DinoV wanted a name that had something with “Python” – the “Py” part – and something with “JIT” – the “JI” part – and have it be pronounceable.

Main features

  • Profile Guided JIT Compiler
  • Native 64-bit float and integer support
  • Small, fast compiler
  • Windows, macOS and Linux
  • Intel and ARM CPU support
  • Builtin IL and ASM disassembler
  • Support for native debugging and profiling tools

Technology

Pyjion compiles native CPython bytecode into machine code. Without Pyjion, CPython uses a master evaluation loop (called the frame evaluation loop) to iterate over opcodes. The Pyjion compiler has 3 main stages:

  • Build a “stack table” of the abstract types at each opcode position
  • Compile CPython opcodes into IL (ECMA335 CIL) instructions
  • Emit the CIL opcodes into the .NET EE compiler to convert to native machine code/assembly

Benchmarks

Benchmarks conducted by the project’s maintainers show that Pyjion is about two to three times faster than regular Python for real-world work.

Pyjion Benchmarks
Python 3.10 vs Python 3.10 + Pyjion

Some of the optimizations allow speedups of up to 10 times. Regular arithmetic, always a good candidate for being JIT-optimized, can be an order of magnitude faster.

Limitations

Some Python features, like with statements or async..await statements are not yet implemented. Both are on the roadmap. Pyjion includes a middleware layer that allows WSGI applications to run on Pyjion. Long-running applications such as web apps are good candidates for JIT acceleration.

Installation

Pyjion requires:

After following the installation steps, Pyjion is just a Python module that you can import into your Python environment:

1
python -m pip install pyjion

After importing Pyjion, enable the JIT using the enable function:

1
2
import pyjion
pyjion.enable()

Any Python code you write or import after enabling Pyjion will be JIT compiled. You don’t need to execute functions in any special API, it’s completely transparent:

1
2
3
4
>>> def half(x):
...    return x/2
>>> half(2)
1.0

You can also execute Pyjion against any script or module:

1
pyjion my_script.py

Or, for an existing Python module:

1
pyjion -m calendar

That’s it!

Comparison

How Pyjion compares to:

PyPy

PyPy is an implementation of Python with its own JIT. The biggest difference compared to Pyjion is that PyPy doesn’t support all C extension modules without modification unless they use CFFI or work with the select subset of CPython’s C API that PyPy does support. Pyjion also aims to support many JIT compilers while PyPy only supports their custom JIT compiler.

Pyston

Pyston is an implementation of Python using LLVM as a JIT compiler. Compared to Pyjion, Pyston has partial CPython C API support but not complete support. Pyston also only supports LLVM as a JIT compiler.

Numba

Numba is a JIT compiler for “array-oriented and math-heavy Python code”. This means that Numba is focused on scientific computing while Pyjion tries to optimize all Python code. Numba also only supports LLVM.

IronPython

IronPython is an implementation of Python that is implemented using .NET. While IronPython tries to be usable from within .NET, Pyjion does not have a compatibility story with .NET. This also means IronPython cannot use C extension modules while Pyjion can.

Nuitka, Shedskin

Both Nuitka and Shedskin are Python-to-C++ transpilers, which means they translate Python code into equivalent C++ code. Being a JIT, Pyjion is not a transpiler.