python_reference/tutorials/running_cython.ipynb

1002 lines
96 KiB
Plaintext
Raw Normal View History

2014-06-12 13:52:01 +00:00
{
"metadata": {
"name": "",
2014-07-07 02:48:40 +00:00
"signature": "sha256:c53d1aaf41825ecf8aae8e9e7691d07f984de379cd765b3cabd973cfb29cc420"
2014-06-12 13:52:01 +00:00
},
"nbformat": 3,
"nbformat_minor": 0,
"worksheets": [
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"[Sebastian Raschka](http://sebastianraschka.com) \n",
2014-07-07 02:35:00 +00:00
"\n",
"[Link to this IPython notebook on GitHub](https://github.com/rasbt/python_reference/blob/master/tutorials/running_cython.ipynb)"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"%load_ext watermark"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 1
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"%watermark -d -m -v -p cython"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"06/07/2014 \n",
"\n",
"CPython 3.4.1\n",
"IPython 2.1.0\n",
"\n",
"cython 0.20.2\n",
"\n",
"compiler : GCC 4.2.1 (Apple Inc. build 5577)\n",
"system : Darwin\n",
"release : 13.2.0\n",
"machine : x86_64\n",
"processor : i386\n",
"CPU cores : 2\n",
"interpreter: 64bit\n"
]
}
],
"prompt_number": 2
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<font size=\"1.5em\">[More information](http://nbviewer.ipython.org/github/rasbt/python_reference/blob/master/ipython_magic/watermark.ipynb) about the `watermark` magic command extension.</font>"
2014-06-12 13:52:01 +00:00
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<hr>\n",
"I would be happy to hear your comments and suggestions. \n",
"Please feel free to drop me a note via\n",
"[twitter](https://twitter.com/rasbt), [email](mailto:bluewoodtree@gmail.com), or [google+](https://plus.google.com/118404394130788869227).\n",
"<hr>"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<a name=\"sections\"></a>\n",
"<br>\n",
"<br>\n"
]
},
{
"cell_type": "heading",
"level": 1,
"metadata": {},
"source": [
"Using Cython with and without IPython magic"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<a name=\"introduction\"></a>\n",
"<br>\n",
"<br>"
]
},
2014-07-07 02:48:40 +00:00
{
"cell_type": "heading",
"level": 1,
"metadata": {},
"source": [
"Sections"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"- [Bubblesort in regular (C)Python](#bubblesort-cpython)\n",
"- [Bubblesort implemented in Cython](#Bubblesort-implemented-in-Cython)\n",
" - [Naive Cython implementation - auto-guessing types](#Naive-Cython-implementation---auto-guessing-types)\n",
" - [Cython with explicit type-declarations](#Cython-with-explicit-type-declarations)\n",
"- [Speed comparison](#Speed-comparison)\n",
"- [How to use Cython without the IPython magic](#How-to-use-Cython-without-the-IPython-magic)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<a name=\"introduction\"></a>\n",
"<br>\n",
"<br>"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<a id='bubblesort-cpython'></a>"
]
},
2014-06-12 13:52:01 +00:00
{
"cell_type": "heading",
2014-07-07 02:35:00 +00:00
"level": 2,
2014-06-12 13:52:01 +00:00
"metadata": {},
"source": [
"Bubblesort in regular (C)Python"
]
},
2014-07-07 02:48:40 +00:00
{
"cell_type": "markdown",
"metadata": {},
"source": [
"[[back to top](#Sections)]"
]
},
2014-06-12 13:52:01 +00:00
{
"cell_type": "markdown",
"metadata": {},
"source": [
"First, we will write a simple implementation of the bubble sort algorithm in regular (C)Python"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"def python_bubblesort(a_list):\n",
" \"\"\" Bubblesort in Python for list objects. \"\"\"\n",
" length = len(a_list)\n",
" swapped = 1\n",
" for i in range(0, length):\n",
" if swapped: \n",
" swapped = 0\n",
" for ele in range(0, length-i-1):\n",
" if a_list[ele] > a_list[ele + 1]:\n",
" temp = a_list[ele + 1]\n",
" a_list[ele + 1] = a_list[ele]\n",
" a_list[ele] = temp\n",
" swapped = 1\n",
" return a_list"
],
"language": "python",
"metadata": {},
"outputs": [],
2014-07-07 02:35:00 +00:00
"prompt_number": 3
2014-06-12 13:52:01 +00:00
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"python_bubblesort([6,3,1,5,6])"
],
"language": "python",
"metadata": {},
"outputs": [
{
"metadata": {},
"output_type": "pyout",
2014-07-07 02:35:00 +00:00
"prompt_number": 4,
2014-06-12 13:52:01 +00:00
"text": [
"[1, 3, 5, 6, 6]"
]
}
],
2014-07-07 02:35:00 +00:00
"prompt_number": 4
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<br>\n",
"<br>"
]
2014-06-12 13:52:01 +00:00
},
{
"cell_type": "heading",
"level": 2,
"metadata": {},
"source": [
2014-07-07 02:35:00 +00:00
"Bubblesort implemented in Cython"
2014-06-12 13:52:01 +00:00
]
},
2014-07-07 02:48:40 +00:00
{
"cell_type": "markdown",
"metadata": {},
"source": [
"[[back to top](#Sections)]"
]
},
2014-06-12 13:52:01 +00:00
{
"cell_type": "markdown",
"metadata": {},
"source": [
2014-07-07 02:35:00 +00:00
"Next, we will speed things up a little bit via [Cython's C-extensions for Python](http://cython.org). Cython is basically a hybrid between C and Python and can be pictured as compiled Python code with type declarations. \n",
"Since we are working in an IPython notebook here, we can make use of the very convenient ***IPython magic***: It will take care of the conversion to C code, the compilation, and eventually the loading of the function. "
2014-06-12 13:52:01 +00:00
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"%load_ext cythonmagic"
],
"language": "python",
"metadata": {},
"outputs": [],
2014-07-07 02:35:00 +00:00
"prompt_number": 5
2014-06-12 13:52:01 +00:00
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
2014-07-07 02:35:00 +00:00
"First, we will take the initial Python code as is and use Cython for the compilation. Cython is capable of auto-guessing types, however, we can make our code way more efficient by adding static types."
]
},
{
"cell_type": "heading",
"level": 4,
"metadata": {},
"source": [
"Naive Cython implementation - auto-guessing types"
2014-06-12 13:52:01 +00:00
]
},
2014-07-07 02:48:40 +00:00
{
"cell_type": "markdown",
"metadata": {},
"source": [
"[[back to top](#Sections)]"
]
},
2014-06-12 13:52:01 +00:00
{
"cell_type": "code",
"collapsed": false,
"input": [
"%%cython\n",
"def cython_bubblesort_untyped(a_list):\n",
" \"\"\" Bubblesort in Python for list objects. \"\"\"\n",
" length = len(a_list)\n",
" swapped = 1\n",
" for i in range(0, length):\n",
" if swapped: \n",
" swapped = 0\n",
" for ele in range(0, length-i-1):\n",
" if a_list[ele] > a_list[ele + 1]:\n",
" temp = a_list[ele + 1]\n",
" a_list[ele + 1] = a_list[ele]\n",
" a_list[ele] = temp\n",
" swapped = 1\n",
" return a_list"
],
"language": "python",
"metadata": {},
"outputs": [],
2014-07-07 02:35:00 +00:00
"prompt_number": 6
},
{
"cell_type": "heading",
"level": 4,
"metadata": {},
"source": [
"Cython with explicit type-declarations"
]
2014-06-12 13:52:01 +00:00
},
2014-07-07 02:48:40 +00:00
{
"cell_type": "markdown",
"metadata": {},
"source": [
"[[back to top](#Sections)]"
]
},
2014-06-12 13:52:01 +00:00
{
"cell_type": "code",
"collapsed": false,
"input": [
"%%cython\n",
"import numpy as np\n",
"cimport numpy as np\n",
"cimport cython\n",
"@cython.boundscheck(False) \n",
"@cython.wraparound(False)\n",
2014-07-07 02:35:00 +00:00
"cpdef cython_bubblesort_typed(np.ndarray[long, ndim=1] inp_ary):\n",
2014-06-12 13:52:01 +00:00
" \"\"\" The Cython implementation of Bubblesort with NumPy memoryview.\"\"\"\n",
" cdef unsigned long length, i, swapped, ele, temp\n",
" cdef long[:] np_ary = inp_ary\n",
" length = np_ary.shape[0]\n",
" swapped = 1\n",
" for i in xrange(0, length):\n",
" if swapped: \n",
" swapped = 0\n",
" for ele in xrange(0, length-i-1):\n",
" if np_ary[ele] > np_ary[ele + 1]:\n",
" temp = np_ary[ele + 1]\n",
" np_ary[ele + 1] = np_ary[ele]\n",
" np_ary[ele] = temp\n",
" swapped = 1\n",
" return inp_ary"
],
"language": "python",
"metadata": {},
"outputs": [],
2014-07-07 02:35:00 +00:00
"prompt_number": 7
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<br>\n",
"<br>"
]
2014-06-12 13:52:01 +00:00
},
{
"cell_type": "heading",
"level": 2,
"metadata": {},
"source": [
"Speed comparison"
]
},
2014-07-07 02:48:40 +00:00
{
"cell_type": "markdown",
"metadata": {},
"source": [
"[[back to top](#Sections)]"
]
},
2014-06-12 13:52:01 +00:00
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Below, we will do a quick speed comparison of our 3 implementations of the bubble sort algorithm by sorting a list (or numpy array) of 1000 random digits. Here, we have to make copies of the lists/numpy arrays, since our bubble sort implementation is sorting in place."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"import random\n",
"import numpy as np\n",
"import copy\n",
"\n",
"list_a = [random.randint(0,1000) for num in range(1000)]\n",
2014-07-07 02:35:00 +00:00
"list_b = copy.deepcopy(list_a)\n",
2014-06-12 13:52:01 +00:00
"\n",
"ary_a = np.asarray(list_a)\n",
"ary_b = copy.deepcopy(ary_a)\n",
"ary_c = copy.deepcopy(ary_a)"
],
"language": "python",
"metadata": {},
"outputs": [],
2014-07-07 02:35:00 +00:00
"prompt_number": 8
2014-06-12 13:52:01 +00:00
},
{
"cell_type": "code",
"collapsed": false,
"input": [
2014-07-07 02:35:00 +00:00
"import timeit\n",
"\n",
"times = []\n",
"\n",
"times.append(min(timeit.Timer('python_bubblesort(list_a)', \n",
" 'from __main__ import python_bubblesort, list_a').repeat(repeat=3, number=1000)))\n",
2014-06-12 13:52:01 +00:00
"\n",
2014-07-07 02:35:00 +00:00
"times.append(min(timeit.Timer('python_bubblesort(ary_a)', \n",
" 'from __main__ import python_bubblesort, ary_a').repeat(repeat=3, number=1000)))\n",
2014-06-12 13:52:01 +00:00
"\n",
2014-07-07 02:35:00 +00:00
"times.append(min(timeit.Timer('cython_bubblesort_untyped(list_b)', \n",
" 'from __main__ import cython_bubblesort_untyped, list_b').repeat(repeat=3, number=1000)))\n",
2014-06-12 13:52:01 +00:00
"\n",
2014-07-07 02:35:00 +00:00
"times.append(min(timeit.Timer('cython_bubblesort_untyped(ary_b)', \n",
" 'from __main__ import cython_bubblesort_untyped, ary_b').repeat(repeat=3, number=1000)))\n",
2014-06-12 13:52:01 +00:00
"\n",
2014-07-07 02:35:00 +00:00
"times.append(min(timeit.Timer('cython_bubblesort_typed(ary_c)', \n",
" 'from __main__ import cython_bubblesort_typed, ary_c').repeat(repeat=3, number=1000)))\n",
"\n"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 9
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"%matplotlib inline"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 10
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"from matplotlib import pyplot as plt\n",
"import numpy as np\n",
"\n",
"bar_labels = ('(C)Python on list', \n",
" '(C)Python on numpy array', \n",
" 'untyped Cython on list', \n",
" 'untyped Cython on numpy array', \n",
" 'typed Cython with memoryview on numpy array')\n",
"\n",
"fig = plt.figure(figsize=(10,8))\n",
"\n",
"# plot bars\n",
"y_pos = np.arange(len(times))\n",
"plt.yticks(y_pos, bar_labels, fontsize=14)\n",
"bars = plt.barh(y_pos, times,\n",
" align='center', alpha=0.4, color='g')\n",
"\n",
"# annotation and labels\n",
"\n",
"for b,d in zip(bars, times):\n",
" plt.text(max(times)+0.1, b.get_y() + b.get_height()/2.5, \n",
" '{:.2} ms'.format(d),\n",
" ha='center', va='bottom', fontsize=12)\n",
"\n",
"t = plt.title('Bubblesort on 1000 random integers', fontsize=18)\n",
"plt.ylim([-1,len(times)+0.5])\n",
"plt.vlines(min(times), -1, len(times)+0.5, linestyles='dashed')\n",
"plt.grid()\n",
"\n",
"plt.show()"
2014-06-12 13:52:01 +00:00
],
"language": "python",
"metadata": {},
"outputs": [
{
2014-07-07 02:35:00 +00:00
"metadata": {},
"output_type": "display_data",
"png": "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\nRAKcz7/8E3ECvS2RHH83K2dy
2014-06-12 13:52:01 +00:00
"text": [
2014-07-07 02:35:00 +00:00
"<matplotlib.figure.Figure at 0x105dd0978>"
2014-06-12 13:52:01 +00:00
]
}
],
2014-07-07 02:35:00 +00:00
"prompt_number": 15
2014-06-12 13:52:01 +00:00
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<br>\n",
"<br>\n",
"As we can see from the results above, we are already able to make our Python code run almost as twice as fast if we compile it via Cython (Python on list: 332 \u00b5s, untyped Cython on list: 183 \u00b5s). \n",
"However, although it is more \"work\" to adjust the Python code, the \"typed Cython with memoryview on numpy array\" is significantly as expected."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<a name=\"cython_bonus\"></a>\n",
"<br>\n",
"<br>"
]
},
{
"cell_type": "heading",
"level": 1,
"metadata": {},
"source": [
"How to use Cython without the IPython magic"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"[[back to top](#sections)]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"IPython's notebook is really great for explanatory analysis and documentation, but what if we want to compile our Python code via Cython without letting IPython's magic doing all the work? \n",
"These are the steps you would need."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<br>\n",
"<br>"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### 1. Creating a .pyx file containing the the desired code or function."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"%%file cython_bubblesort_nomagic.pyx\n",
"\n",
2014-07-07 02:35:00 +00:00
"cimport numpy as np\n",
"cimport cython\n",
"@cython.boundscheck(False) \n",
"@cython.wraparound(False)\n",
"cpdef cython_bubblesort_nomagic(np.ndarray[long, ndim=1] inp_ary):\n",
2014-06-12 13:52:01 +00:00
" \"\"\" The Cython implementation of Bubblesort with NumPy memoryview.\"\"\"\n",
" cdef unsigned long length, i, swapped, ele, temp\n",
" cdef long[:] np_ary = inp_ary\n",
" length = np_ary.shape[0]\n",
" swapped = 1\n",
" for i in xrange(0, length):\n",
" if swapped: \n",
" swapped = 0\n",
" for ele in xrange(0, length-i-1):\n",
" if np_ary[ele] > np_ary[ele + 1]:\n",
" temp = np_ary[ele + 1]\n",
" np_ary[ele + 1] = np_ary[ele]\n",
" np_ary[ele] = temp\n",
" swapped = 1\n",
" return inp_ary"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
2014-07-07 02:35:00 +00:00
"Writing cython_bubblesort_nomagic.pyx\n"
2014-06-12 13:52:01 +00:00
]
}
],
"prompt_number": 16
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<br>\n",
"<br>"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### 2. Creating a simple setup file"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"%%file setup.py\n",
"\n",
2014-07-07 02:35:00 +00:00
"import numpy as np\n",
2014-06-12 13:52:01 +00:00
"from distutils.core import setup\n",
"from distutils.extension import Extension\n",
"from Cython.Distutils import build_ext\n",
"\n",
"setup(\n",
" cmdclass = {'build_ext': build_ext},\n",
2014-07-07 02:35:00 +00:00
" ext_modules = [\n",
" Extension(\"cython_bubblesort_nomagic\",\n",
" [\"cython_bubblesort_nomagic.pyx\"],\n",
" include_dirs=[np.get_include()])\n",
" ]\n",
2014-06-12 13:52:01 +00:00
")"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
2014-07-07 02:35:00 +00:00
"Writing setup.py\n"
2014-06-12 13:52:01 +00:00
]
}
],
"prompt_number": 17
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<br>\n",
"<br>\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"####3. Building and Compiling"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"!python3 setup.py build_ext --inplace"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"running build_ext\r\n"
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
"cythoning cython_bubblesort_nomagic.pyx to cython_bubblesort_nomagic.c\r\n"
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
"building 'cython_bubblesort_nomagic' extension\r\n",
2014-07-07 02:35:00 +00:00
"/usr/bin/clang -fno-strict-aliasing -Werror=declaration-after-statement -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes -I/Users/sebastian/miniconda3/envs/py34/include -arch x86_64 -I/Users/sebastian/miniconda3/envs/py34/lib/python3.4/site-packages/numpy/core/include -I/Users/sebastian/miniconda3/envs/py34/include/python3.4m -c cython_bubblesort_nomagic.c -o build/temp.macosx-10.5-x86_64-3.4/cython_bubblesort_nomagic.o\r\n"
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
"In file included from cython_bubblesort_nomagic.c:352:\r\n",
"In file included from /Users/sebastian/miniconda3/envs/py34/lib/python3.4/site-packages/numpy/core/include/numpy/arrayobject.h:4:\r\n",
"In file included from /Users/sebastian/miniconda3/envs/py34/lib/python3.4/site-packages/numpy/core/include/numpy/ndarrayobject.h:17:\r\n",
"In file included from /Users/sebastian/miniconda3/envs/py34/lib/python3.4/site-packages/numpy/core/include/numpy/ndarraytypes.h:1761:\r\n",
"\u001b[1m/Users/sebastian/miniconda3/envs/py34/lib/python3.4/site-packages/numpy/core/include/numpy/npy_1_7_deprecated_api.h:15:2: \u001b[0m\u001b[0;1;35mwarning: \u001b[0m\u001b[1m\r\n",
" \"Using deprecated NumPy API, disable it by \" \"#defining\r\n",
" NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION\" [-W#warnings]\u001b[0m\r\n",
"#warning \"Using deprecated NumPy API, disable it by \" \\\r\n",
"\u001b[0;1;32m ^\r\n",
"\u001b[0m"
2014-06-12 13:52:01 +00:00
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
2014-07-07 02:35:00 +00:00
"In file included from cython_bubblesort_nomagic.c:352:\r\n",
"In file included from /Users/sebastian/miniconda3/envs/py34/lib/python3.4/site-packages/numpy/core/include/numpy/arrayobject.h:4:\r\n",
"In file included from /Users/sebastian/miniconda3/envs/py34/lib/python3.4/site-packages/numpy/core/include/numpy/ndarrayobject.h:26:\r\n",
"\u001b[1m/Users/sebastian/miniconda3/envs/py34/lib/python3.4/site-packages/numpy/core/include/numpy/__multiarray_api.h:1629:1: \u001b[0m\u001b[0;1;35mwarning: \u001b[0m\u001b[1m\r\n",
" unused function '_import_array' [-Wunused-function]\u001b[0m\r\n",
"_import_array(void)\r\n",
"\u001b[0;1;32m^\r\n",
"\u001b[0mIn file included from cython_bubblesort_nomagic.c:353:\r\n",
"In file included from /Users/sebastian/miniconda3/envs/py34/lib/python3.4/site-packages/numpy/core/include/numpy/ufuncobject.h:327:\r\n",
"\u001b[1m/Users/sebastian/miniconda3/envs/py34/lib/python3.4/site-packages/numpy/core/include/numpy/__ufunc_api.h:241:1: \u001b[0m\u001b[0;1;35mwarning: \u001b[0m\u001b[1m\r\n",
" unused function '_import_umath' [-Wunused-function]\u001b[0m\r\n",
"_import_umath(void)\r\n",
"\u001b[0;1;32m^\r\n",
"\u001b[0m\u001b[1mcython_bubblesort_nomagic.c:18981:32: \u001b[0m\u001b[0;1;35mwarning: \u001b[0m\u001b[1munused function\r\n",
2014-06-12 13:52:01 +00:00
" '__Pyx_PyUnicode_FromString' [-Wunused-function]\u001b[0m\r\n",
2014-07-07 02:35:00 +00:00
"static CYTHON_INLINE PyObject* __Pyx_PyUnicode_FromString(const char* c_str) {\r\n",
2014-06-12 13:52:01 +00:00
"\u001b[0;1;32m ^\r\n",
2014-07-07 02:35:00 +00:00
"\u001b[0m\u001b[1mcython_bubblesort_nomagic.c:19132:33: \u001b[0m\u001b[0;1;35mwarning: \u001b[0m\u001b[1munused function\r\n",
2014-06-12 13:52:01 +00:00
" '__Pyx_PyInt_FromSize_t' [-Wunused-function]\u001b[0m\r\n",
"static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t ival) {\r\n",
"\u001b[0;1;32m ^\r\n",
2014-07-07 02:35:00 +00:00
"\u001b[0m\u001b[1mcython_bubblesort_nomagic.c:16538:1: \u001b[0m\u001b[0;1;35mwarning: \u001b[0m\u001b[1munused function\r\n",
2014-06-12 13:52:01 +00:00
" '__pyx_add_acquisition_count_locked' [-Wunused-function]\u001b[0m\r\n",
"__pyx_add_acquisition_count_locked(__pyx_atomic_int *acquisition_count,\r\n",
"\u001b[0;1;32m^\r\n",
2014-07-07 02:35:00 +00:00
"\u001b[0m\u001b[1mcython_bubblesort_nomagic.c:16548:1: \u001b[0m\u001b[0;1;35mwarning: \u001b[0m\u001b[1munused function\r\n",
2014-06-12 13:52:01 +00:00
" '__pyx_sub_acquisition_count_locked' [-Wunused-function]\u001b[0m\r\n",
"__pyx_sub_acquisition_count_locked(__pyx_atomic_int *acquisition_count,\r\n",
"\u001b[0;1;32m^\r\n",
2014-07-07 02:35:00 +00:00
"\u001b[0m\u001b[1mcython_bubblesort_nomagic.c:17017:26: \u001b[0m\u001b[0;1;35mwarning: \u001b[0m\u001b[1munused function\r\n",
2014-06-12 13:52:01 +00:00
" '__Pyx_PyBytes_Equals' [-Wunused-function]\u001b[0m\r\n",
"static CYTHON_INLINE int __Pyx_PyBytes_Equals(PyObject* s1, PyObject* s2...\r\n",
"\u001b[0;1;32m ^\r\n",
2014-07-07 02:35:00 +00:00
"\u001b[0m\u001b[1mcython_bubblesort_nomagic.c:17298:32: \u001b[0m\u001b[0;1;35mwarning: \u001b[0m\u001b[1munused function\r\n",
" '__Pyx_GetItemInt_List_Fast' [-Wunused-function]\u001b[0m\r\n",
2014-06-12 13:52:01 +00:00
"static CYTHON_INLINE PyObject *__Pyx_GetItemInt_List_Fast(PyObject *o, P...\r\n",
"\u001b[0;1;32m ^\r\n",
2014-07-07 02:35:00 +00:00
"\u001b[0m\u001b[1mcython_bubblesort_nomagic.c:17312:32: \u001b[0m\u001b[0;1;35mwarning: \u001b[0m\u001b[1munused function\r\n",
2014-06-12 13:52:01 +00:00
" '__Pyx_GetItemInt_Tuple_Fast' [-Wunused-function]\u001b[0m\r\n",
"static CYTHON_INLINE PyObject *__Pyx_GetItemInt_Tuple_Fast(PyObject *o, ...\r\n",
"\u001b[0;1;32m ^\r\n",
2014-07-07 02:35:00 +00:00
"\u001b[0m\u001b[1mcython_bubblesort_nomagic.c:17491:38: \u001b[0m\u001b[0;1;35mwarning: \u001b[0m\u001b[1munused function\r\n",
2014-06-12 13:52:01 +00:00
" '__Pyx_PyInt_From_unsigned_long' [-Wunused-function]\u001b[0m\r\n",
" static CYTHON_INLINE PyObject* __Pyx_PyInt_From_unsigned_long(unsi...\r\n",
"\u001b[0;1;32m ^\r\n",
2014-07-07 02:35:00 +00:00
"\u001b[0m\u001b[1mcython_bubblesort_nomagic.c:17538:36: \u001b[0m\u001b[0;1;35mwarning: \u001b[0m\u001b[1mfunction\r\n",
2014-06-12 13:52:01 +00:00
" '__Pyx_PyInt_As_unsigned_long' is not needed and will not be emitted\r\n",
" [-Wunneeded-internal-declaration]\u001b[0m\r\n",
"static CYTHON_INLINE unsigned long __Pyx_PyInt_As_unsigned_long(PyObject *x) {\r\n",
"\u001b[0;1;32m ^\r\n",
2014-07-07 02:35:00 +00:00
"\u001b[0m\u001b[1mcython_bubblesort_nomagic.c:17644:48: \u001b[0m\u001b[0;1;35mwarning: \u001b[0m\u001b[1munused function\r\n",
" '__pyx_t_float_complex_from_parts' [-Wunused-function]\u001b[0m\r\n",
" static CYTHON_INLINE __pyx_t_float_complex __pyx_t_float_complex_fro...\r\n",
"\u001b[0;1;32m ^\r\n",
"\u001b[0m\u001b[1mcython_bubblesort_nomagic.c:17654:30: \u001b[0m\u001b[0;1;35mwarning: \u001b[0m\u001b[1munused function '__Pyx_c_eqf'\r\n",
" [-Wunused-function]\u001b[0m\r\n",
" static CYTHON_INLINE int __Pyx_c_eqf(__pyx_t_float_complex a, __pyx_...\r\n",
"\u001b[0;1;32m ^\r\n",
"\u001b[0m\u001b[1mcython_bubblesort_nomagic.c:17657:48: \u001b[0m\u001b[0;1;35mwarning: \u001b[0m\u001b[1munused function '__Pyx_c_sumf'\r\n",
" [-Wunused-function]\u001b[0m\r\n",
" static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_sumf(__pyx_t_floa...\r\n",
"\u001b[0;1;32m ^\r\n",
"\u001b[0m\u001b[1mcython_bubblesort_nomagic.c:17663:48: \u001b[0m\u001b[0;1;35mwarning: \u001b[0m\u001b[1munused function '__Pyx_c_difff'\r\n",
" [-Wunused-function]\u001b[0m\r\n",
" static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_difff(__pyx_t_flo...\r\n",
"\u001b[0;1;32m ^\r\n",
"\u001b[0m\u001b[1mcython_bubblesort_nomagic.c:17675:48: \u001b[0m\u001b[0;1;35mwarning: \u001b[0m\u001b[1munused function '__Pyx_c_quotf'\r\n",
" [-Wunused-function]\u001b[0m\r\n",
" static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_quotf(__pyx_t_flo...\r\n",
"\u001b[0;1;32m ^\r\n",
"\u001b[0m\u001b[1mcython_bubblesort_nomagic.c:17682:48: \u001b[0m\u001b[0;1;35mwarning: \u001b[0m\u001b[1munused function '__Pyx_c_negf'\r\n",
" [-Wunused-function]\u001b[0m\r\n",
" static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_negf(__pyx_t_floa...\r\n",
"\u001b[0;1;32m ^\r\n",
"\u001b[0m\u001b[1mcython_bubblesort_nomagic.c:17688:30: \u001b[0m\u001b[0;1;35mwarning: \u001b[0m\u001b[1munused function\r\n",
" '__Pyx_c_is_zerof' [-Wunused-function]\u001b[0m\r\n",
" static CYTHON_INLINE int __Pyx_c_is_zerof(__pyx_t_float_complex a) {\r\n",
"\u001b[0;1;32m ^\r\n",
"\u001b[0m\u001b[1mcython_bubblesort_nomagic.c:17691:48: \u001b[0m\u001b[0;1;35mwarning: \u001b[0m\u001b[1munused function '__Pyx_c_conjf'\r\n",
" [-Wunused-function]\u001b[0m\r\n",
" static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_conjf(__pyx_t_flo...\r\n",
"\u001b[0;1;32m ^\r\n",
"\u001b[0m\u001b[1mcython_bubblesort_nomagic.c:17705:52: \u001b[0m\u001b[0;1;35mwarning: \u001b[0m\u001b[1munused function '__Pyx_c_powf'\r\n",
" [-Wunused-function]\u001b[0m\r\n",
" static CYTHON_INLINE __pyx_t_float_complex __Pyx_c_powf(__pyx_t_...\r\n",
"\u001b[0;1;32m ^\r\n",
"\u001b[0m\u001b[1mcython_bubblesort_nomagic.c:17764:49: \u001b[0m\u001b[0;1;35mwarning: \u001b[0m\u001b[1munused function\r\n",
" '__pyx_t_double_complex_from_parts' [-Wunused-function]\u001b[0m\r\n",
" static CYTHON_INLINE __pyx_t_double_complex __pyx_t_double_complex_f...\r\n",
"\u001b[0;1;32m ^\r\n",
"\u001b[0m\u001b[1mcython_bubblesort_nomagic.c:17774:30: \u001b[0m\u001b[0;1;35mwarning: \u001b[0m\u001b[1munused function '__Pyx_c_eq'\r\n",
" [-Wunused-function]\u001b[0m\r\n",
" static CYTHON_INLINE int __Pyx_c_eq(__pyx_t_double_complex a, __pyx_...\r\n",
"\u001b[0;1;32m ^\r\n",
"\u001b[0m\u001b[1mcython_bubblesort_nomagic.c:17777:49: \u001b[0m\u001b[0;1;35mwarning: \u001b[0m\u001b[1munused function '__Pyx_c_sum'\r\n",
" [-Wunused-function]\u001b[0m\r\n",
" static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_sum(__pyx_t_doub...\r\n",
"\u001b[0;1;32m ^\r\n",
"\u001b[0m\u001b[1mcython_bubblesort_nomagic.c:17783:49: \u001b[0m\u001b[0;1;35mwarning: \u001b[0m\u001b[1munused function '__Pyx_c_diff'\r\n",
" [-Wunused-function]\u001b[0m\r\n",
" static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_diff(__pyx_t_dou...\r\n",
"\u001b[0;1;32m ^\r\n",
"\u001b[0m\u001b[1mcython_bubblesort_nomagic.c:17795:49: \u001b[0m\u001b[0;1;35mwarning: \u001b[0m\u001b[1munused function '__Pyx_c_quot'\r\n",
" [-Wunused-function]\u001b[0m\r\n",
" static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_quot(__pyx_t_dou...\r\n",
"\u001b[0;1;32m ^\r\n",
"\u001b[0m\u001b[1mcython_bubblesort_nomagic.c:17802:49: \u001b[0m\u001b[0;1;35mwarning: \u001b[0m\u001b[1munused function '__Pyx_c_neg'\r\n",
" [-Wunused-function]\u001b[0m\r\n",
" static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_neg(__pyx_t_doub...\r\n",
"\u001b[0;1;32m ^\r\n",
"\u001b[0m\u001b[1mcython_bubblesort_nomagic.c:17808:30: \u001b[0m\u001b[0;1;35mwarning: \u001b[0m\u001b[1munused function '__Pyx_c_is_zero'\r\n",
" [-Wunused-function]\u001b[0m\r\n",
" static CYTHON_INLINE int __Pyx_c_is_zero(__pyx_t_double_complex a) {\r\n",
"\u001b[0;1;32m ^\r\n",
"\u001b[0m\u001b[1mcython_bubblesort_nomagic.c:17811:49: \u001b[0m\u001b[0;1;35mwarning: \u001b[0m\u001b[1munused function '__Pyx_c_conj'\r\n",
" [-Wunused-function]\u001b[0m\r\n",
" static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_conj(__pyx_t_dou...\r\n",
"\u001b[0;1;32m ^\r\n",
"\u001b[0m\u001b[1mcython_bubblesort_nomagic.c:17825:53: \u001b[0m\u001b[0;1;35mwarning: \u001b[0m\u001b[1munused function '__Pyx_c_pow'\r\n",
" [-Wunused-function]\u001b[0m\r\n",
" static CYTHON_INLINE __pyx_t_double_complex __Pyx_c_pow(__pyx_t_...\r\n",
"\u001b[0;1;32m ^\r\n",
"\u001b[0m\u001b[1mcython_bubblesort_nomagic.c:18247:27: \u001b[0m\u001b[0;1;35mwarning: \u001b[0m\u001b[1mfunction '__Pyx_PyInt_As_char' is\r\n",
2014-06-12 13:52:01 +00:00
" not needed and will not be emitted [-Wunneeded-internal-declaration]\u001b[0m\r\n",
"static CYTHON_INLINE char __Pyx_PyInt_As_char(PyObject *x) {\r\n",
"\u001b[0;1;32m ^\r\n",
2014-07-07 02:35:00 +00:00
"\u001b[0m\u001b[1mcython_bubblesort_nomagic.c:18347:27: \u001b[0m\u001b[0;1;35mwarning: \u001b[0m\u001b[1mfunction '__Pyx_PyInt_As_long' is\r\n",
2014-06-12 13:52:01 +00:00
" not needed and will not be emitted [-Wunneeded-internal-declaration]\u001b[0m\r\n",
"static CYTHON_INLINE long __Pyx_PyInt_As_long(PyObject *x) {\r\n",
"\u001b[0;1;32m ^\r\n",
2014-07-07 02:35:00 +00:00
"\u001b[0m\u001b[1mcython_bubblesort_nomagic.c:2955:32: \u001b[0m\u001b[0;1;35mwarning: \u001b[0m\u001b[1munused function\r\n",
" '__pyx_f_5numpy_PyArray_MultiIterNew1' [-Wunused-function]\u001b[0m\r\n",
"static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew1(PyOb...\r\n",
"\u001b[0;1;32m ^\r\n",
"\u001b[0m\u001b[1mcython_bubblesort_nomagic.c:3005:32: \u001b[0m\u001b[0;1;35mwarning: \u001b[0m\u001b[1munused function\r\n",
" '__pyx_f_5numpy_PyArray_MultiIterNew2' [-Wunused-function]\u001b[0m\r\n",
"static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew2(PyOb...\r\n",
"\u001b[0;1;32m ^\r\n",
"\u001b[0m\u001b[1mcython_bubblesort_nomagic.c:3055:32: \u001b[0m\u001b[0;1;35mwarning: \u001b[0m\u001b[1munused function\r\n",
" '__pyx_f_5numpy_PyArray_MultiIterNew3' [-Wunused-function]\u001b[0m\r\n",
"static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew3(PyOb...\r\n",
"\u001b[0;1;32m ^\r\n",
"\u001b[0m\u001b[1mcython_bubblesort_nomagic.c:3105:32: \u001b[0m\u001b[0;1;35mwarning: \u001b[0m\u001b[1munused function\r\n",
" '__pyx_f_5numpy_PyArray_MultiIterNew4' [-Wunused-function]\u001b[0m\r\n",
"static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew4(PyOb...\r\n",
"\u001b[0;1;32m ^\r\n",
"\u001b[0m\u001b[1mcython_bubblesort_nomagic.c:3155:32: \u001b[0m\u001b[0;1;35mwarning: \u001b[0m\u001b[1munused function\r\n",
" '__pyx_f_5numpy_PyArray_MultiIterNew5' [-Wunused-function]\u001b[0m\r\n",
"static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew5(PyOb...\r\n",
"\u001b[0;1;32m ^\r\n",
"\u001b[0m\u001b[1mcython_bubblesort_nomagic.c:3909:27: \u001b[0m\u001b[0;1;35mwarning: \u001b[0m\u001b[1munused function\r\n",
" '__pyx_f_5numpy_set_array_base' [-Wunused-function]\u001b[0m\r\n",
"static CYTHON_INLINE void __pyx_f_5numpy_set_array_base(PyArrayObject *_...\r\n",
"\u001b[0;1;32m ^\r\n",
"\u001b[0m\u001b[1mcython_bubblesort_nomagic.c:3997:32: \u001b[0m\u001b[0;1;35mwarning: \u001b[0m\u001b[1munused function\r\n",
" '__pyx_f_5numpy_get_array_base' [-Wunused-function]\u001b[0m\r\n",
"static CYTHON_INLINE PyObject *__pyx_f_5numpy_get_array_base(PyArrayObje...\r\n",
"\u001b[0;1;32m ^\r\n",
2014-06-12 13:52:01 +00:00
"\u001b[0m"
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
2014-07-07 02:35:00 +00:00
"39 warnings generated.\r\n",
"/usr/bin/clang -bundle -undefined dynamic_lookup -L/Users/sebastian/miniconda3/envs/py34/lib -arch x86_64 build/temp.macosx-10.5-x86_64-3.4/cython_bubblesort_nomagic.o -L/Users/sebastian/miniconda3/envs/py34/lib -o /Users/sebastian/github/python_reference/tutorials/cython_bubblesort_nomagic.so\r\n"
2014-06-12 13:52:01 +00:00
]
}
],
"prompt_number": 18
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### 4. Importing and running the code"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"import cython_bubblesort_nomagic\n",
"\n",
"cython_bubblesort_nomagic.cython_bubblesort_nomagic(np.array([4,6,2,1,6]))"
],
"language": "python",
"metadata": {},
"outputs": [
{
"metadata": {},
"output_type": "pyout",
2014-07-07 02:35:00 +00:00
"prompt_number": 19,
2014-06-12 13:52:01 +00:00
"text": [
"array([1, 2, 4, 6, 6])"
]
}
],
2014-07-07 02:35:00 +00:00
"prompt_number": 19
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<br>\n",
"<br>"
]
},
{
"cell_type": "heading",
"level": 2,
"metadata": {},
"source": [
"Speed comparison"
]
},
2014-07-07 02:48:40 +00:00
{
"cell_type": "markdown",
"metadata": {},
"source": [
"[[back to top](#Sections)]"
]
},
2014-07-07 02:35:00 +00:00
{
"cell_type": "code",
"collapsed": false,
"input": [
"from cython_bubblesort_nomagic import cython_bubblesort_nomagic\n",
"\n",
"list_a = [random.randint(0,100000) for num in range(100000)]\n",
"\n",
"ary_a = np.asarray(list_a)\n",
"ary_b = np.asarray(list_a)\n",
"\n",
"times = []\n",
"\n",
"times.append(min(timeit.Timer('cython_bubblesort_typed(ary_a)', \n",
" 'from __main__ import cython_bubblesort_typed, ary_a').repeat(repeat=3, number=1000)))\n",
"\n",
"times.append(min(timeit.Timer('cython_bubblesort_nomagic(ary_b)', \n",
" 'from __main__ import cython_bubblesort_nomagic, ary_b').repeat(repeat=3, number=1000)))"
],
"language": "python",
"metadata": {},
"outputs": [],
2014-06-12 13:52:01 +00:00
"prompt_number": 20
},
2014-07-07 02:35:00 +00:00
{
"cell_type": "code",
"collapsed": false,
"input": [
"from matplotlib import pyplot as plt\n",
"import numpy as np\n",
"\n",
"bar_labels = ('Cython with IPython magic', \n",
" 'Cython without IPython magic')\n",
"\n",
"fig = plt.figure(figsize=(10,8))\n",
"\n",
"# plot bars\n",
"y_pos = np.arange(len(times))\n",
"plt.yticks(y_pos, bar_labels, fontsize=14)\n",
"bars = plt.barh(y_pos, times,\n",
" align='center', alpha=0.4, color='g')\n",
"\n",
"# annotation and labels\n",
"\n",
"for b,d in zip(bars, times):\n",
" plt.text(max(times)+0.02, b.get_y() + b.get_height()/2.5, \n",
" '{:.2} ms'.format(d),\n",
" ha='center', va='bottom', fontsize=12)\n",
"\n",
"t = plt.title('Bubblesort on 100,000 random integers', fontsize=18)\n",
"plt.ylim([-1,len(times)+0.5])\n",
"plt.vlines(min(times), -1, len(times)+0.5, linestyles='dashed')\n",
"plt.grid()\n",
"\n",
"plt.show()"
],
"language": "python",
"metadata": {},
"outputs": [
{
"metadata": {},
"output_type": "display_data",
"png": "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\nXEb7e2Ykjca9gughavb3hDLh
"text": [
"<matplotlib.figure.Figure at 0x105844390>"
]
}
],
"prompt_number": 21
},
2014-06-12 13:52:01 +00:00
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<a name=\"numba\"></a>\n",
"<br>\n",
"<br>"
]
}
],
"metadata": {}
}
]
}