Skip to content

Instantly share code, notes, and snippets.

@BertrandBordage
Created January 25, 2014 16:27
Show Gist options
  • Save BertrandBordage/8618934 to your computer and use it in GitHub Desktop.
Save BertrandBordage/8618934 to your computer and use it in GitHub Desktop.
Cython simple class benchmark
Display the source blob
Display the rendered blob
Raw
{
"metadata": {
"name": ""
},
"nbformat": 3,
"nbformat_minor": 0,
"worksheets": [
{
"cells": [
{
"cell_type": "heading",
"level": 1,
"metadata": {},
"source": [
"Performance comparison between a basic Python class and its Cython equivalent"
]
},
{
"cell_type": "heading",
"level": 2,
"metadata": {},
"source": [
"Python class"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"class Point(object): \n",
" def __init__(self, x=0.0, y=0.0):\n",
" self.x = x\n",
" self.y = y\n",
"\n",
" @property\n",
" def position(self):\n",
" return self.x + self.y*1.0j\n",
"\n",
" @position.setter\n",
" def position(self, v):\n",
" self.x = v.real\n",
" self.y = v.imag\n",
"\n",
" def add(self, other):\n",
" self.x += other.x\n",
" self.y += other.y\n",
"\n",
" def __add__(self, other):\n",
" new = Point(self.x, self.y)\n",
" new.add(other)\n",
" return new\n",
"\n",
" def __repr__(self):\n",
" return '<Point (%f %f)>' % (self.x, self.y)"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 1
},
{
"cell_type": "heading",
"level": 2,
"metadata": {},
"source": [
"Cython extension type"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"%load_ext cythonmagic"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 2
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"%%cython\n",
"\n",
"\n",
"cdef class cPoint(object):\n",
" cdef public float x, y\n",
"\n",
" def __cinit__(self, float x=0.0, float y=0.0):\n",
" self.x = x\n",
" self.y = y\n",
"\n",
" property position:\n",
" def __get__(self):\n",
" return self.x + self.y*1.0j\n",
"\n",
" def __set__(self, complex v):\n",
" self.x = v.real\n",
" self.y = v.imag\n",
"\n",
" cpdef add(self, cPoint other):\n",
" self.x += other.x\n",
" self.y += other.y\n",
"\n",
" def __add__(self, cPoint other):\n",
" cdef cPoint new = cPoint(self.x, self.y)\n",
" new.add(other)\n",
" return new\n",
"\n",
" def __repr__(self):\n",
" return '<Point (%f %f)>' % (self.x, self.y)"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 3
},
{
"cell_type": "heading",
"level": 2,
"metadata": {},
"source": [
"Tests"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Each test measures the execution time of Python then Cython."
]
},
{
"cell_type": "heading",
"level": 4,
"metadata": {},
"source": [
"Setup"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"p = Point(5.0, 3.0)\n",
"p2 = Point(4.0)\n",
"\n",
"cp = cPoint(5.0, 3.0)\n",
"cp2 = cPoint(4.0)"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 4
},
{
"cell_type": "heading",
"level": 4,
"metadata": {},
"source": [
"Instantiation without arguments"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"%timeit Point()\n",
"%timeit cPoint()"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"1000000 loops, best of 3: 324 ns per loop\n",
"10000000 loops, best of 3: 65.5 ns per loop"
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
"\n"
]
}
],
"prompt_number": 5
},
{
"cell_type": "heading",
"level": 4,
"metadata": {},
"source": [
"Instantiation with arguments"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"%timeit Point(1.0, 2.0)\n",
"%timeit cPoint(1.0, 2.0)"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"1000000 loops, best of 3: 351 ns per loop\n",
"10000000 loops, best of 3: 90.4 ns per loop"
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
"\n"
]
}
],
"prompt_number": 6
},
{
"cell_type": "heading",
"level": 4,
"metadata": {},
"source": [
"Instantiation with arguments of a bad type (this only affects Cython)"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"%timeit Point(1, 2)\n",
"%timeit cPoint(1, 2)"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"1000000 loops, best of 3: 353 ns per loop\n",
"10000000 loops, best of 3: 176 ns per loop"
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
"\n"
]
}
],
"prompt_number": 7
},
{
"cell_type": "heading",
"level": 4,
"metadata": {},
"source": [
"Gets the \"position\" property"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"%timeit p.position\n",
"%timeit cp.position"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"1000000 loops, best of 3: 302 ns per loop\n",
"10000000 loops, best of 3: 61.4 ns per loop"
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
"\n"
]
}
],
"prompt_number": 8
},
{
"cell_type": "heading",
"level": 4,
"metadata": {},
"source": [
"Sets the \"position\" property"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"%timeit p.position = 2 - 3j\n",
"%timeit cp.position = 2 - 3j"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"1000000 loops, best of 3: 264 ns per loop\n",
"10000000 loops, best of 3: 46.5 ns per loop"
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
"\n"
]
}
],
"prompt_number": 9
},
{
"cell_type": "heading",
"level": 4,
"metadata": {},
"source": [
"\"add\" method"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"%timeit p.add(p2)\n",
"%timeit cp.add(cp2)"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"1000000 loops, best of 3: 418 ns per loop\n",
"10000000 loops, best of 3: 76.7 ns per loop"
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
"\n"
]
}
],
"prompt_number": 10
},
{
"cell_type": "heading",
"level": 4,
"metadata": {},
"source": [
"Addition"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"%timeit p + p2\n",
"%timeit cp + cp2"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"1000000 loops, best of 3: 1.01 \u00b5s per loop\n",
"10000000 loops, best of 3: 144 ns per loop"
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
"\n"
]
}
],
"prompt_number": 11
},
{
"cell_type": "heading",
"level": 4,
"metadata": {},
"source": [
"Representation"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"%timeit repr(p)\n",
"%timeit repr(cp)"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"1000000 loops, best of 3: 961 ns per loop\n",
"1000000 loops, best of 3: 771 ns per loop"
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
"\n"
]
}
],
"prompt_number": 12
}
],
"metadata": {}
}
]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment