hi there serta jaegerdaup here for infoworld at idg in this episode of smart python i'm going
to take a look at some new aspects of the cython project a way to compile python code to c for the
sake of speed syphon has been adding new syntax to make the language less jarring for existing
python users and today we're going to take a look at how that new syntax works and how you
can make it work for you first a quick overview of cython itself in previous videos i've talked
about cython as a way to take python code add type decorations for it essentially making your python
code use c types instead of python objects and gain significant speedups from doing so
the biggest speedups come from translating math operations on c types like integers and floats or
areas of those primitives python doesn't deal well with working with those things natively
cython generates c code that does and can run many times faster than its python equivalents
now to use cython you have to write code using a syntax exclusive to python existing python code
will compile into cython but it won't show much if any performance gain what's more the
syntax for cython can be a little off-putting to python users since it harkens back to c itself
however over time cython's creators have added an alternate syntax to psython one rooted in the way
python's own syntax works such as its type hinting system it's called pure python mode and while it
doesn't yet fully replace the original cython syntax it provides us with two big advantages
one you can write a functional python version of your code using cython's
new syntax and you can continue to run it as python even with the cython declarations in it
this makes it easier to progressively accelerate your code with more psython specific syntax
number two you can continue to use your existing python linting and formatting tools cython syntax
meant formatting tools like black and checking tools like pyrite wouldn't function correctly
but the pure python syntax for cython means you can use those tools as you would for any other
python code to demonstrate this i'm going to show you examples of the classic and pure python mode
syntax side by side using the same project this project by the way is a slightly revised version
of the project that i used in a previous video to demonstrate cython originally
it's an implementation of the mathematical game conway's game of life
which simulates the life cycle of a colony of cells according to mathematical rules
and since it's highly math intensive it's a great candidate for being sped up through cython
here we have the original cython code for this project and at a glance it's pretty readable
even for someone who doesn't know cython's custom syntax and we can get code highlighting for it
here in visual studio code by way of a kind soul who wrote a python syntax highlighting extension
but we still have to wade through cython's type declaration syntax and it's funky custom syntax
for declaring cython objects like c def which is how we declare things like cython functions
and even if we get used to all of that we're still locked out of using all of our familiar
tools for python we can't run black to format this code for instance because the custom syntax will
throw it off now let's take a look at the same project written in cython's pure python syntax
now several things pop out right away first is that this looks a lot more like actual python
when we have type hints they're in python's regular type hinting format and we use the
cython import up here to provide those so they're not magic additions to the code we can understand
where they actually come from also things like type casts which are commonly used in c
and also in cython 2 are done by we have regular python syntax instead of the c like casting syntax
used in cython which is hard to follow and clashes badly with the rest of python syntax
when we want to declare a cython level function or class we don't use a custom keyword anymore as we
did in original cython where we used cdf instead we take our function or class and we wrap it in
a decorator cython.cfunc to create a c-level function and cython.c class for c-level class
another really important difference is that we can use attributes in the imported cython
module to make decisions at runtime based on whether or not this code has been compiled to c
in this block here we do this by checking the value of the cython dot compiled attribute
if we're running a compiled version of this code then we perform one set of imports
but if we're still in regular python mode we perform a different set of imports
and likewise here later in the code we make other decisions based on whether or not we're
in compiled mode if we are in compiled mode all the non-compiled code branches
will be automatically removed so there's no performance impact when we compile the c
if we're still running in regular python mode the total impact for this amounts to a single if test
now you will want to avoid putting such tests in tight loops to avoid unnecessarily slowing
down non-compiled code paths but for the most part this has very little impact
so here i've used this feature to make this code run in both regular unoptimized mode
and in compiled mode so this is a great way to prototype code in python slowly and then
accelerate it incrementally this gives us our slow and our fast code paths for the same jobs
side by side in the same code base so let's run this code in regular unoptimized python mode first
what you're seeing here by the way is the simulation of the lives and deaths of a
colony of cells according to a set of mathematical rules the flashes of red that you see our cells
dying the flashes of blue you see our cells being born and the green is the cells that
survive across generations now unfortunately the uncompiled version of this code is slow
very slow according to the statistics i'm harvesting from the program in real time
it takes .04 seconds to render each generation and around 0.027 seconds to draw that to the screen
if we want this to run at anything like 30 or 60 frames a second we can't do this in regular
python mode it just isn't going to work we have to compile it so let's close out of that version
of the program and compile it to c the compilation process doesn't take very long because we actually
don't have that much code here cython works best when you use it to optimize a few small hotspots
in your code that eat up the most runtime with this program things like the window and the
input handling system are all still done in pure python because they're not a significant source
of the program speed bottlenecks all of that stuff is in the actual computation so now let's run with
the c compiled version of this module and first off you can see how much faster it is just off
the bat the render time for each generation is several hundred times faster than it was before
as is the draw time i'm running this program at 30 frames per second so that you can see it in this
capture but in theory we could run it a thousand frames per second so again the big advantages
of pure python mode for cython are twofold one it lets us use the syntax and the tooling that we're
familiar with through the rest of python both the current and future versions and two it lets
us do more of what cython promises to begin with which is being able to take regular python code
and speed it up bit by bit with type information and optimizations that only cython can provide
incidentally there's been talk over the years about whether type annotations in python would
lead to a statically typed version of the language one that could be better optimized for speed
my personal feeling is that we've had that for a long time in the form of cython
and now with the pure python mode for cython growing that much more mature
we have it more now than ever that's it for this video if you liked it please leave a comment below
don't forget to subscribe to the idg techtalk channel on youtube and for more smart python
and more device serdar be sure to follow me on facebook youtube and infoworld.com