Skip to content

Instantly share code, notes, and snippets.

@adamkal
Last active August 29, 2015 13:56
Show Gist options
  • Save adamkal/9171081 to your computer and use it in GitHub Desktop.
Save adamkal/9171081 to your computer and use it in GitHub Desktop.
namedtuple performance tests
Display the source blob
Display the rendered blob
Raw
{
"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