Skip to content

Instantly share code, notes, and snippets.

@dionhaefner
Created September 26, 2016 18:05
Show Gist options
  • Save dionhaefner/ebe44c480b141be162a5452fe24113bc to your computer and use it in GitHub Desktop.
Save dionhaefner/ebe44c480b141be162a5452fe24113bc to your computer and use it in GitHub Desktop.
Display the source blob
Display the rendered blob
Raw
{
"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