Created
September 26, 2016 18:05
-
-
Save dionhaefner/ebe44c480b141be162a5452fe24113bc to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"cells": [ | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"## Naive Python implementation" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 1, | |
"metadata": { | |
"collapsed": true | |
}, | |
"outputs": [], | |
"source": [ | |
"class PyAnimal:\n", | |
" i = 0\n", | |
" def do_stuff(self):\n", | |
" self.i += 1 \n", | |
" def state(self):\n", | |
" return self.i\n", | |
" \n", | |
"class PyPopulation:\n", | |
" def __init__(self,animals):\n", | |
" self.animals = animals\n", | |
" def do_stuff(self):\n", | |
" for animal in self.animals:\n", | |
" animal.do_stuff()" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 32, | |
"metadata": { | |
"collapsed": false | |
}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"100 loops, best of 3: 17.9 ms per loop\n" | |
] | |
}, | |
{ | |
"data": { | |
"text/plain": [ | |
"411" | |
] | |
}, | |
"execution_count": 32, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"animals = [PyAnimal() for i in range(100000)]\n", | |
"population = PyPopulation(animals)\n", | |
"%timeit population.do_stuff()\n", | |
"population.animals[15].state()" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"## Naive Cython implementation" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 4, | |
"metadata": { | |
"collapsed": false | |
}, | |
"outputs": [], | |
"source": [ | |
"%load_ext cython" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 28, | |
"metadata": { | |
"collapsed": false | |
}, | |
"outputs": [], | |
"source": [ | |
"%%cython\n", | |
"cdef class CyAnimal:\n", | |
" cdef int i\n", | |
" \n", | |
" cpdef void do_stuff(self):\n", | |
" self.i += 1\n", | |
" \n", | |
" cpdef int state(self):\n", | |
" return self.i\n", | |
"\n", | |
"cdef class CyPopulation:\n", | |
" cdef list animals\n", | |
" \n", | |
" def __init__(self,list animals):\n", | |
" self.animals = animals\n", | |
" \n", | |
" cpdef void do_stuff(self):\n", | |
" for animal in self.animals:\n", | |
" animal.do_stuff()\n", | |
" \n", | |
" cpdef list state(self):\n", | |
" return [animal.state() for animal in self.animals]" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 29, | |
"metadata": { | |
"collapsed": false | |
}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"100 loops, best of 3: 3.08 ms per loop\n" | |
] | |
}, | |
{ | |
"data": { | |
"text/plain": [ | |
"411" | |
] | |
}, | |
"execution_count": 29, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"animals = [CyAnimal() for i in range(100000)]\n", | |
"population = CyPopulation(animals)\n", | |
"%timeit population.do_stuff()\n", | |
"population.state()[15]" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"## C++ wrapper implementation" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 8, | |
"metadata": { | |
"collapsed": false | |
}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"Overwriting cppanimal.h\n" | |
] | |
} | |
], | |
"source": [ | |
"%%writefile cppanimal.h\n", | |
"\n", | |
"class CppAnimal {\n", | |
" public:\n", | |
" int i;\n", | |
" CppAnimal():i(0) {}\n", | |
" void do_stuff() {\n", | |
" i++;\n", | |
" }\n", | |
" int state() {\n", | |
" return i;\n", | |
" }\n", | |
"};" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 24, | |
"metadata": { | |
"collapsed": false | |
}, | |
"outputs": [], | |
"source": [ | |
"%%cython -+ -I .\n", | |
"from libcpp.vector cimport vector\n", | |
"from cython.operator cimport dereference as deref, preincrement as inc\n", | |
"\n", | |
"\"\"\"\n", | |
"Expose interface from C++ class\n", | |
"\"\"\"\n", | |
"cdef extern from \"cppanimal.h\":\n", | |
" cdef cppclass CppAnimal:\n", | |
" CppAnimal()\n", | |
" void do_stuff()\n", | |
" int state()\n", | |
"\n", | |
"\"\"\"\n", | |
"Since CppAnimal is a C++ class, we cannot interact with it from Python.\n", | |
"The population class thus has to create the Animals through a method.\n", | |
"\"\"\"\n", | |
"cdef class CyPopulation2:\n", | |
" cdef vector[CppAnimal] animals\n", | |
" \n", | |
" cpdef create_animal(self):\n", | |
" self.animals.push_back(CppAnimal())\n", | |
" \n", | |
" cpdef void do_stuff(self):\n", | |
" cdef vector[CppAnimal].iterator it = self.animals.begin()\n", | |
" while it != self.animals.end():\n", | |
" deref(it).do_stuff()\n", | |
" inc(it)\n", | |
" \n", | |
" cpdef list state(self):\n", | |
" return [a.state() for a in self.animals]" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 25, | |
"metadata": { | |
"collapsed": false | |
}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"10000 loops, best of 3: 53.7 µs per loop\n" | |
] | |
}, | |
{ | |
"data": { | |
"text/plain": [ | |
"41111" | |
] | |
}, | |
"execution_count": 25, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"population = CyPopulation2()\n", | |
"[population.create_animal() for _ in range(100000)]\n", | |
"%timeit population.do_stuff()\n", | |
"population.state()[15]" | |
] | |
} | |
], | |
"metadata": { | |
"kernelspec": { | |
"display_name": "Python 2", | |
"language": "python", | |
"name": "python2" | |
}, | |
"language_info": { | |
"codemirror_mode": { | |
"name": "ipython", | |
"version": 2 | |
}, | |
"file_extension": ".py", | |
"mimetype": "text/x-python", | |
"name": "python", | |
"nbconvert_exporter": "python", | |
"pygments_lexer": "ipython2", | |
"version": "2.7.12" | |
} | |
}, | |
"nbformat": 4, | |
"nbformat_minor": 1 | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment