Last active
August 29, 2015 13:56
-
-
Save adamkal/9171081 to your computer and use it in GitHub Desktop.
namedtuple performance tests
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": "code", | |
"collapsed": false, | |
"input": [ | |
"from functools import partial\n", | |
"from timeit import Timer\n", | |
"from IPython import display\n", | |
"\n", | |
"ITERATIONS = 1000000\n", | |
"SHORT_ITERATIONS = ITERATIONS / 1000\n", | |
"REPEAT_TIMES = 5" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [], | |
"prompt_number": 1 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"def _compare_results(baseline, first, second, first_label=\"namedtuple\", second_label=\"tuple\"):\n", | |
" first_best = min(first)\n", | |
" second_best = min(second)\n", | |
"\n", | |
" slower = first_best > second_best\n", | |
" \n", | |
" results = \"\"\"\n", | |
" <table>\n", | |
" <tr>\n", | |
" <th>baseline</th>\n", | |
" <th>{first}</th>\n", | |
" <th>{second}</th>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <td>{:.3f}s</td>\n", | |
" <td>{:.1f}x</td>\n", | |
" <td>{:.1f}x</td>\n", | |
" </tr>\n", | |
" </table>\n", | |
" \"\"\".format(baseline, first_best/baseline, second_best/baseline, first=first_label, second=second_label)\n", | |
" \n", | |
" conclusion = \"{first} is <em>{:.2f}x</em> <strong>{}</strong> then {second}\"\n", | |
" if slower:\n", | |
" results += conclusion.format(first_best / second_best, 'slower', first=first_label, second=second_label)\n", | |
" else:\n", | |
" results += conclusion.format(second_best / first_best, 'faster', first=first_label, second=second_label)\n", | |
" return results" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [], | |
"prompt_number": 2 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"# reusable setup parts\n", | |
"common_setup = \"a, b, c, d = 1, 'x', {}, []\"\n", | |
"\n", | |
"namedtuple_import = \"from collections import namedtuple\"\n", | |
"namedtuple_create = \"T = namedtuple('T', 'a b c d')\"\n", | |
"namedtuple_create_instance = \"t = T(a, b, c, 4)\"\n", | |
"namedtuple_access_index = \"t[2]\"\n", | |
"namedtuple_access_attr = \"t.c\"\n", | |
"\n", | |
"tuple_create_instance = \"t = (a, b, c, 4)\"\n", | |
"tuple_access = namedtuple_access_index" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [], | |
"prompt_number": 3 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"# baseline\n", | |
"\n", | |
"baseline_timer = Timer(\"pass\")\n", | |
"baseline = min(baseline_timer.repeat(REPEAT_TIMES, number=ITERATIONS))\n", | |
"baseline_short = min(baseline_timer.repeat(REPEAT_TIMES, SHORT_ITERATIONS))\n", | |
"\n", | |
"compare_results = partial(_compare_results, baseline)\n", | |
"compare_short_results = partial(_compare_results, baseline_short)" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [], | |
"prompt_number": 4 | |
}, | |
{ | |
"cell_type": "heading", | |
"level": 2, | |
"metadata": {}, | |
"source": [ | |
"Create named tuple" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"namedtuple_creation_timer = Timer('T = namedtuple(\"T\", \"a\")',\n", | |
" setup=namedtuple_import)\n", | |
"nt_time = namedtuple_creation_timer.repeat(REPEAT_TIMES, SHORT_ITERATIONS)\n", | |
"\n", | |
"class_creation_timer = Timer(\"\"\"\n", | |
"class T(object):\n", | |
" #__slots__ = ['a']\n", | |
" \n", | |
" def __init__(self, a):\n", | |
" self.a = a\n", | |
"\"\"\")\n", | |
"class_time = class_creation_timer.repeat(REPEAT_TIMES, SHORT_ITERATIONS)\n", | |
"\n", | |
"\n", | |
"display.HTML(compare_short_results(nt_time, class_time, second_label='simple class'))" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"html": [ | |
"\n", | |
" <table>\n", | |
" <tr>\n", | |
" <th>baseline</th>\n", | |
" <th>namedtuple</th>\n", | |
" <th>simple class</th>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <td>0.000s</td>\n", | |
" <td>33155.4x</td>\n", | |
" <td>789.6x</td>\n", | |
" </tr>\n", | |
" </table>\n", | |
" namedtuple is <em>41.99x</em> <strong>slower</strong> then simple class" | |
], | |
"metadata": {}, | |
"output_type": "pyout", | |
"prompt_number": 5, | |
"text": [ | |
"<IPython.core.display.HTML at 0x10d7bf610>" | |
] | |
} | |
], | |
"prompt_number": 5 | |
}, | |
{ | |
"cell_type": "heading", | |
"level": 2, | |
"metadata": {}, | |
"source": [ | |
"Instance creation" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"# create instance\n", | |
"\n", | |
"nt_setup = '\\n'.join([\n", | |
" namedtuple_import,\n", | |
" namedtuple_create,\n", | |
" common_setup\n", | |
"])\n", | |
"\n", | |
"t_setup = '\\n'.join([\n", | |
" common_setup\n", | |
"])\n", | |
"\n", | |
"time_of = lambda timer: timer.repeat(REPEAT_TIMES, number=ITERATIONS)\n", | |
"\n", | |
"nt_builder = partial(Timer, setup=nt_setup)\n", | |
"t_builder = partial(Timer, setup=t_setup)\n", | |
"\n", | |
"results = \"\"\n", | |
"\n", | |
"for arguments in [\"(1, 2, 3, 4)\", \"({}, {}, {}, {})\", \"(a, b, c, d)\"]:\n", | |
" nt_create_instance_timer = nt_builder(\"t = T{}\".format(arguments))\n", | |
" t_create_instance_timer = t_builder(\"t = {}\".format(arguments))\n", | |
" \n", | |
" nt_time = time_of(nt_create_instance_timer)\n", | |
" t_time = time_of(t_create_instance_timer)\n", | |
" results += \"<h4>Arguments: {}</h4>\".format(arguments)\n", | |
" results += compare_results(nt_time, t_time)\n", | |
" \n", | |
"nt_time = time_of(nt_builder(\"t = T(a=a, b=b, c=c, d=d)\"))\n", | |
"results += \"<h4>Keyword arguments (a=a, b=b, c=c, d=d)</h4>\".format(arguments)\n", | |
"results += compare_results(nt_time, t_time)\n", | |
" \n", | |
"display.HTML(\"<div>{}</div>\".format(results))" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"html": [ | |
"<div><h4>Arguments: (1, 2, 3, 4)</h4>\n", | |
" <table>\n", | |
" <tr>\n", | |
" <th>baseline</th>\n", | |
" <th>namedtuple</th>\n", | |
" <th>tuple</th>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <td>0.013s</td>\n", | |
" <td>41.0x</td>\n", | |
" <td>1.6x</td>\n", | |
" </tr>\n", | |
" </table>\n", | |
" namedtuple is <em>25.83x</em> <strong>slower</strong> then tuple<h4>Arguments: ({}, {}, {}, {})</h4>\n", | |
" <table>\n", | |
" <tr>\n", | |
" <th>baseline</th>\n", | |
" <th>namedtuple</th>\n", | |
" <th>tuple</th>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <td>0.013s</td>\n", | |
" <td>46.3x</td>\n", | |
" <td>9.6x</td>\n", | |
" </tr>\n", | |
" </table>\n", | |
" namedtuple is <em>4.82x</em> <strong>slower</strong> then tuple<h4>Arguments: (a, b, c, d)</h4>\n", | |
" <table>\n", | |
" <tr>\n", | |
" <th>baseline</th>\n", | |
" <th>namedtuple</th>\n", | |
" <th>tuple</th>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <td>0.013s</td>\n", | |
" <td>40.4x</td>\n", | |
" <td>4.6x</td>\n", | |
" </tr>\n", | |
" </table>\n", | |
" namedtuple is <em>8.78x</em> <strong>slower</strong> then tuple<h4>Keyword arguments (a=a, b=b, c=c, d=d)</h4>\n", | |
" <table>\n", | |
" <tr>\n", | |
" <th>baseline</th>\n", | |
" <th>namedtuple</th>\n", | |
" <th>tuple</th>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <td>0.013s</td>\n", | |
" <td>60.6x</td>\n", | |
" <td>4.6x</td>\n", | |
" </tr>\n", | |
" </table>\n", | |
" namedtuple is <em>13.17x</em> <strong>slower</strong> then tuple</div>" | |
], | |
"metadata": {}, | |
"output_type": "pyout", | |
"prompt_number": 9, | |
"text": [ | |
"<IPython.core.display.HTML at 0x10e090310>" | |
] | |
} | |
], | |
"prompt_number": 9 | |
}, | |
{ | |
"cell_type": "heading", | |
"level": 2, | |
"metadata": {}, | |
"source": [ | |
"Accessing data" | |
] | |
}, | |
{ | |
"cell_type": "heading", | |
"level": 3, | |
"metadata": {}, | |
"source": [ | |
"By index" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"# access by index\n", | |
"\n", | |
"namedtuple_create_instance_timer = Timer(namedtuple_access_index,\n", | |
" setup='\\n'.join([namedtuple_import,\n", | |
" namedtuple_create,\n", | |
" common_setup,\n", | |
" namedtuple_create_instance]))\n", | |
"nt_time = namedtuple_create_instance_timer.repeat(REPEAT_TIMES, number=ITERATIONS)\n", | |
"\n", | |
"tuple_create_instance_timer = Timer(tuple_access, setup='\\n'.join([common_setup,\n", | |
" tuple_create_instance]))\n", | |
"t_time = tuple_create_instance_timer.repeat(REPEAT_TIMES, number=ITERATIONS)\n", | |
"\n", | |
"display.HTML(compare_results(nt_time, t_time))" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"html": [ | |
"\n", | |
" <table>\n", | |
" <tr>\n", | |
" <th>baseline</th>\n", | |
" <th>namedtuple</th>\n", | |
" <th>tuple</th>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <td>0.013s</td>\n", | |
" <td>3.5x</td>\n", | |
" <td>3.5x</td>\n", | |
" </tr>\n", | |
" </table>\n", | |
" namedtuple is <em>1.00x</em> <strong>faster</strong> then tuple" | |
], | |
"metadata": {}, | |
"output_type": "pyout", | |
"prompt_number": 7, | |
"text": [ | |
"<IPython.core.display.HTML at 0x10e119990>" | |
] | |
} | |
], | |
"prompt_number": 7 | |
}, | |
{ | |
"cell_type": "heading", | |
"level": 3, | |
"metadata": {}, | |
"source": [ | |
"By attribute" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"namedtuple_create_instance_timer = Timer(namedtuple_access_attr,\n", | |
" setup='\\n'.join([namedtuple_import,\n", | |
" namedtuple_create,\n", | |
" common_setup,\n", | |
" namedtuple_create_instance]))\n", | |
"nt_time = namedtuple_create_instance_timer.repeat(REPEAT_TIMES, number=ITERATIONS)\n", | |
"\n", | |
"display.HTML(compare_results(nt_time, t_time))" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"html": [ | |
"\n", | |
" <table>\n", | |
" <tr>\n", | |
" <th>baseline</th>\n", | |
" <th>namedtuple</th>\n", | |
" <th>tuple</th>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <td>0.013s</td>\n", | |
" <td>11.5x</td>\n", | |
" <td>3.5x</td>\n", | |
" </tr>\n", | |
" </table>\n", | |
" namedtuple is <em>3.27x</em> <strong>slower</strong> then tuple" | |
], | |
"metadata": {}, | |
"output_type": "pyout", | |
"prompt_number": 8, | |
"text": [ | |
"<IPython.core.display.HTML at 0x10e1199d0>" | |
] | |
} | |
], | |
"prompt_number": 8 | |
} | |
], | |
"metadata": {} | |
} | |
] | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment