Created
January 25, 2014 16:27
-
-
Save BertrandBordage/8618934 to your computer and use it in GitHub Desktop.
Cython simple class benchmark
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
{ | |
"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