Thursday, May 28, 2009

Python on the .NET Framework: There's more than one way to do it

IronPython is written in C# and is an implementation of the Python programming language that runs natively on the .NET framework with full access to .NET libraries. It isn't however the only way of using Python with .NET. One disadvantage of IronPython is that unless you are using Ironclad you can't use Python C extensions with IronPython,

One alternative is Python.NET. This is a version of CPython (the normal implementation of Python) which also has integration with the .NET framework. As you would expect you can use Python C extensions with Python.NET, but when you use .NET objects you aren't using them natively but are using a proxied or copied version instead.

There is also a little known third option: PyPy.NET. PyPy is an extremely interesting project - it is both an interpreter compiler toolchain, allowing you to write interpreters for dynamic languages in a high level static language called RPython which is a subset of Python, and a Python interpreter written in RPython.

The compiler toolchain supports compiling for a variety of backends - compiling interpreters to C (the native backend), Java byte-code and also IL (Intermediate Language the .NET bytecode). This means that a single implementation (sourcecode in RPython) can be maintained for all three platforms.

A key feature of PyPy is that the toolchain can also generate and compile specialised JIT compilers for all three backends.

The PyPy team recently blogged about two papers that have been accepted for the ICOOOLPS (Implementation, Compilation, Optimization of Object-Oriented Languages, Programs and Systems) conference. One of these is on the PyPy JIT for .NET:
The relevant paper is "Faster than C#: efficient implementation of dynamic languages on .NET" (PDF) by Armin, Anto and Davide Ancona, who is Anto's Ph.D. advisor.
"Faster than C#" is a deliberately misleading quote. It refers to PyPy's claim (still unproven except for specific benchmarks) that PyPy can be "Faster than C". Faster than C means faster than the C implementation of Python but also alludes to the PyPy team's conviction that dynamic languages need not be slower than statically typed languages like C...

.NET already has a JIT, so it may seem odd for a .NET implementation of Python to also have a JIT. What it permits is for the language to emit efficient and typed bytecode that the .NET JIT is better able to optimise as machine code - a genuine double JITting! The paper does claim to demonstrate that with their approach code written in a dynamic language can run as fast, or faster, than the equivalent code in C#!

The paper abstract describes this:
The Common Language Infrastructure (CLI) is a virtual machine expressly designed for implementing statically typed languages as C#, therefore programs written in dynamically typed languages are typically much slower than C# when executed on .NET.

Recent developments show that Just In Time (JIT) compilers can exploit runtime type information to generate quite efficient code. Unfortunately, writing a JIT compiler is far from being simple.

In this paper we report our positive experience with automatic generation of JIT compilers as supported by the PyPy infrastructure, by focusing on JIT compilation for .NET.

Following this approach, we have in fact added a second layer of JIT compilation, by allowing dynamic generation of more efficient .NET bytecode, which in turn can be compiled to machine code by the .NET JIT compiler.

The main and novel contribution of this paper is to show that this two-layers JIT technique is effective, since programs written in dynamic languages can run on .NET as fast as (and in some cases even faster than) the equivalent C# programs.

The practicality of the approach is demonstrated by showing some promising experiments done with benchmarks written in a simple dynamic language.
Interestingly both Python.NET and PyPy.NET have copied IronPython in makingthe clr module the first point of integration with the Common Language Runtime and use the same syntax as IronPython for creating typed arrays and working with generics. This means that despite their differences code which uses .NET classes and features is 'somewhat portable' between all three implmentations.


  1. Unfortunately, PyPy.NET doesn't yet support delegates. So, its not useful for any serious work.

    Also, Python.NET does not seem to be maintained any longer.

    So, IronPython is really the only show in town for Python/.NET integration.


  2. Python.NET is not very actively developed but there are quite a few people using it (less than IronPython though) and it gets occasional maintenance. It works fine so is definitely viable for some projects.

    But yes, like the rest of PyPy, PyPy.NET is mainly interesting for the future rather than for using at the moment.


Note: only a member of this blog may post a comment.