Python has earned a reputation for being powerful, flexible, and easy to work with. These virtues have led to its use in a huge and growing variety of applications, workflows, and fields. But the design of the language—its interpreted nature, its runtime dynamism—means that Python has always been an order of magnitude slower than machine-native languages like C or C++.
Over the years, developers have come up with a variety of workarounds for Python’s speed limitations. For instance, you could write performance-intensive tasks in C and wrap it with Python; many machine learning libraries do exactly this. Or you could use Cython, a project that lets you sprinkle Python code with runtime type information that allows it to be compiled to C.
But workarounds are never ideal. Wouldn’t it be great if we could just take an existing Python program as is, and run it dramatically faster? That’s exactly what PyPy allows you to do.
PyPy vs. CPython
PyPy is a drop-in replacement for the stock Python interpreter, CPython. Whereas CPython compiles Python to intermediate bytecode that is then interpreted by a virtual machine, PyPy uses just-in-time (JIT) compilation to translate Python code into machine-native assembly language.
Depending on the task being performed, the performance gains can be dramatic. On the average, PyPy speeds up Python by about 7.6 times, with some tasks accelerated 50 times or more. The CPython interpreter simply doesn’t perform the same kinds of optimizations as PyPy, and probably never will, since that is not one of its design goals.
The best part is that little to no effort is required on the part of the developer to unlock the gains PyPy provides. Simply swap out CPython for PyPy, and for the most part you’re done. There are a few exceptions, discussed below, but PyPy’s stated goal is to run existing, unmodified Python code and provide it with an automatic speed boost.