{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "> This is one of the 100 recipes of the [IPython Cookbook](http://ipython-books.github.io/), the definitive guide to high-performance scientific computing and data science in Python.\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# 5.4. Accelerating Python code with Cython" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We use Cython to accelerate the generation of the Mandelbrot fractal." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "import numpy as np" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We initialize the simulation and generate the grid\n", "in the complex plane." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "size = 200\n", "iterations = 100" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Pure Python" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "def mandelbrot_python(m, size, iterations):\n", " for i in range(size):\n", " for j in range(size):\n", " c = -2 + 3./size*j + 1j*(1.5-3./size*i)\n", " z = 0\n", " for n in range(iterations):\n", " if np.abs(z) <= 10:\n", " z = z*z + c\n", " m[i, j] = n\n", " else:\n", " break" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "%%timeit -n1 -r1 m = np.zeros((size, size))\n", "mandelbrot_python(m, size, iterations)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Cython versions" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We first import Cython." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "#%load_ext cythonmagic\n", "%load_ext Cython" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Take 1" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "First, we just add the %%cython magic." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "%%cython -a\n", "import numpy as np\n", "\n", "def mandelbrot_cython(m, size, iterations):\n", " for i in range(size):\n", " for j in range(size):\n", " c = -2 + 3./size*j + 1j*(1.5-3./size*i)\n", " z = 0\n", " for n in range(iterations):\n", " if np.abs(z) <= 10:\n", " z = z*z + c\n", " m[i, j] = n\n", " else:\n", " break" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "%%timeit -n1 -r1 m = np.zeros((size, size), dtype=np.int32)\n", "mandelbrot_cython(m, size, iterations)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Virtually no speedup." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Take 2" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now, we add type information, using memory views for NumPy arrays." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "%%cython -a\n", "import numpy as np\n", "\n", "def mandelbrot_cython(int[:,::1] m, \n", " int size, \n", " int iterations):\n", " cdef int i, j, n\n", " cdef complex z, c\n", " for i in range(size):\n", " for j in range(size):\n", " c = -2 + 3./size*j + 1j*(1.5-3./size*i)\n", " z = 0\n", " for n in range(iterations):\n", " if z.real**2 + z.imag**2 <= 100:\n", " z = z*z + c\n", " m[i, j] = n\n", " else:\n", " break" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "%%timeit -n1 -r1 m = np.zeros((size, size), dtype=np.int32)\n", "mandelbrot_cython(m, size, iterations)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Interesting speedup!" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "> You'll find all the explanations, figures, references, and much more in the book (to be released later this summer).\n", "\n", "> [IPython Cookbook](http://ipython-books.github.io/), by [Cyrille Rossant](http://cyrille.rossant.net), Packt Publishing, 2014 (500 pages)." ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.4.2" } }, "nbformat": 4, "nbformat_minor": 0 }