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