Optimiziongpython
Optimiziongpython
As a result, one of Python’s major drawbacks is its speed. Even for activities at
which Python excels, like string manipulation, Python falls way behind in the
category of “faster” languages.
For a particular String Manipulation Benchmark, the following time results were
achieved for a 4096KB string size: 0:07:17 (Perl), 0:31:09 (PHP), 0:40:55 (Ruby),
0:45:20 (Python), 0:28:51 (C++), 0:09:15 (C).
STRING MANIPULATION
BENCHMARK
Source: http://raid6.com.au/~onlyjob/posts/arena/
CYTHON AND NUMBA
So, what can be done? Aside from tiny improvements that can be made here-and-
there within the code itself, we can also use compiling methods to speed up our
code.
Almost any piece of Python code is also valid Cython code, which the Cython
compiler will convert into C code.
CYTHON
Cython code must, unlike Python, be compiled. This happens in two stages:
•A .pyx file is compiled by Cython to a .c file, containing the code of a Python
extension module.
• The .c file is compiled by a C compiler to a .so file (or .pyd on Windows) which can
be imported directly into a Python session.
HELLO, WORLD!
The basic steps to compiling a Cython extension are as follows:
1. In helloworld.pyx: print "Hello, World!
Also, the Python types list, dict, tuple, etc. may be used for static typing, as well as
any user defined extension types.
STATIC TYPING
Consider the following purely Python code.
def f(x):
return x**2-x
s = 0
dx = (b-a)/N
for i in range(N):
s += f(a+i*dx)
return s * dx
STATIC TYPING
Consider the following purely Python code.
def f(x):
return x**2-x Using Python’s timeit module, the call
integrate_f(0, 5, 100000000) took about
def integrate_f(a, b, N): 4.198 seconds.
s = 0
dx = (b-a)/N By just compiling with Cython, the call took
for i in range(N): about 2.137 seconds.
s += f(a+i*dx)
return s * dx
print(timeit.timeit("integrate_f(0.0,
5.0,10000000)", setup="from cydemo import
integrate_f", number=1))
STATIC TYPING
A Cythonic version of this code might
def f(double x):
look like this: return x**2-x
...
CYTHON FUNCTIONS
Within a Cython module, Python functions and C functions can call each other
freely, but only Python functions can be called from outside the module by
interpreted Python code. So, any functions that you want to “export” from your
Cython module must be declared as Python functions using def.
There is also a hybrid function, called cpdef. A cpdef function can be called from
anywhere, but uses the faster C calling conventions when being called from other
Cython code.
TYPING FUNCTIONS
When using Cython, Python function cdef double f(double x):
calls are extra expensive because one return x**2-x
might need to convert to and from
def integrate_f(double a, double b, int N):
Python objects to do the call. We can
create some more speedup just by cdef int i
typing our functions. cdef double s, dx
s = 0
dx = (b-a)/N
>>> import pyximport
for i in range(N):
>>> pyximport.install()
s += f(a+i*dx)
>>> import cydemo4
return s * dx
0.0377948284149
# timeit code here
SOME RESULTS
• cydemo: pure Python implementation.
• cydemo2: pure Python compiled with Cython.
• cydemo3: static typing.
• cydemo4: static typing and function typing.
# timeit function
SOME RESULTS
Bottom-line: When it really matters, use
Cython or Numba to improve your code’s
• cydemo: pure Python implementation. speed. This is not quite a magic wand –
• cydemo2: pure Python compiled with Cython. these methods increase your
• cydemo3: static typing. dependencies, reduce your readability,
• cydemo4: static typing and function typing. and complicate your development.
• numbademo: jit-compiled functions.
For simple examples like these, Cython
module N = 10000000 N = 100000000 and Numba are not too painful to add in,
cydemo 4.198 41.69 but they may be a headache for more
complicated modules.
cydemo2 2.137 22.74
cydemo3 .663 5.90
See also Dropbox’s Pyston, a JIT
cydemo4 .0377 0.382
compiler for Python.
numbademo .0192 0.191