Experiments with Cython and Tornado

372 views
Skip to first unread message

Ben Darnell

unread,
Jan 19, 2014, 5:14:16 PM1/19/14
to Tornado Mailing List
Cython's ability to compile pure Python code to C is very impressive:  with just a few small (albeit sometimes hacky) changes, I was able to compile all of Tornado, and nearly all of the tests work. This led to a ~25% speedup in the HTTPServer benchmark without even adding any type annotations (although for perspective, pypy gives a greater speed improvement for less work).  I'm not sure it makes sense to try and compile all of Tornado with cython, but it's neat that it's possible. More realistically, it might be beneficial to use cython to speed up a few heavily-used modules that are too complicated to rewrite in pure C like I did for the websocket mask function (the most likely targets are stack_context and gen).

The changes are in my fork of tornado:

The issues I encountered are:

* There is no equivalent to isinstance(x, types.GeneratorType) for cython-compiled generators.  I was forced to look at repr(type(x)) instead.  Cython appears to generate a new generator type object for each module that uses generators, so there is no common base class.

* Similarly, inspect.getargspec() does not work on cython functions, and there is no common base class to identify these functions with isinstance.  They do, however, have all the special introspection attributes used by getargspec (or at least the subset that Tornado needs).

* Cython appears to define class attributes in isolation from each other, so you cannot define one class attribute in terms of another.  

* The `__file__` special variable is only set after the module has been completely evaluated; it is not available at import time.

* Some generators produce a SystemError when compiled with cython, which appears to be a compiler bug.

* sys.getframe() behaves differently, so attempts to determine "who called me" produce different results.  This affects the standard logging module and tornado.options' --help grouping.

* `__future__` imports actually produce objects in standard python, but not in cython.  This is very esoteric, but we had a couple of tests that depend on these objects.

* Cython modules don't support the '__name__ == "__main__"' mode of execution, so entry points must be left uncompiled.

-Ben

Bonneville

unread,
Jan 20, 2014, 9:10:48 AM1/20/14
to python-...@googlegroups.com, b...@bendarnell.com
Sounds great!  As a cython user, type annotation of ints and floats especially in for-loops will significantly improve performance.  The Cython google group is very responsive too.

Ben Darnell

unread,
Jan 20, 2014, 11:00:01 AM1/20/14
to Bonneville, Tornado Mailing List
On Mon, Jan 20, 2014 at 9:10 AM, Bonneville <dinesh...@hotmail.com> wrote:
Sounds great!  As a cython user, type annotation of ints and floats especially in for-loops will significantly improve performance.  The Cython google group is very responsive too.

Yes, the problem is that there is very little code in tornado that deals with numbers or even large loops, so it's unclear how much gain we would see from type annotations (or even where to start for the biggest impact).  

INADA Naoki

unread,
Jan 21, 2014, 4:44:59 AM1/21/14
to python-...@googlegroups.com, Bonneville
cdef / cpdef also improves performance significantly.


--
You received this message because you are subscribed to the Google Groups "Tornado Web Server" group.
To unsubscribe from this group and stop receiving emails from it, send an email to python-tornad...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.



--
INADA Naoki  <songof...@gmail.com>
Reply all
Reply to author
Forward
0 new messages