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 hidden or 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