Skip to content

Instantly share code, notes, and snippets.

@topher200
Created October 14, 2015 07:04
Show Gist options
  • Save topher200/99927146c4ecec754bb3 to your computer and use it in GitHub Desktop.
Save topher200/99927146c4ecec754bb3 to your computer and use it in GitHub Desktop.
ipython notebook for int to string python
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"I've never made an ipython notebook before. Seemed like it might be fun!\n",
"\n",
"The first section is re-implementing the ones from your email."
]
},
{
"cell_type": "code",
"execution_count": 21,
"metadata": {
"collapsed": false,
"scrolled": true
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"'Slow' method:\n",
" 0.302333275477\n",
"Fast method:\n",
" 0.25133339564\n",
"Faster method:\n",
" 0.226666609446\n"
]
}
],
"source": [
"import numpy\n",
"import time\n",
" \n",
"ints = [x for x in xrange(1000, 10000000, 10)]\n",
"\n",
"def timeit(func, name):\n",
" time_deltas = []\n",
" for _ in xrange(10):\n",
" start_time = time.time()\n",
" func()\n",
" time_deltas.append(time.time() - start_time)\n",
" \n",
" print(\"{}:\".format(name))\n",
" best_time_deltas = sorted(time_deltas)[:3]\n",
" print(\" {}\".format(numpy.mean(best_time_deltas)))\n",
"\n",
"def slow():\n",
" new_list = [None] * len(ints)\n",
" for i in xrange(len(ints)):\n",
" new_list[i] = str(ints[i])\n",
"timeit(slow, \"'Slow' method\")\n",
"\n",
"def fast():\n",
" new_list = [str(x) for x in ints]\n",
"timeit(fast, \"Fast method\")\n",
"\n",
"def faster():\n",
" new_list = [x for x in map(str, ints)]\n",
"timeit(faster, \"Faster method\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"I added the slow one just for fun. I shouldn't have bothered."
]
},
{
"cell_type": "code",
"execution_count": 22,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Superfast method:\n",
" 0.162333408991\n"
]
}
],
"source": [
"def superfast():\n",
" new_list = map(str, ints)\n",
"timeit(superfast, \"Superfast method\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Your 'faster' solution in the email seems like it didn't need to include the list comprehension at all. 'Fastest' is the map solution without that extra iteration from the list comprehension. Superfast indeed!"
]
},
{
"cell_type": "code",
"execution_count": 23,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"'Slow' method, with numpy array:\n",
" 0.460000038147\n",
"'Slow' method, with append:\n",
" 0.353666702906\n"
]
}
],
"source": [
"def new_slow_numpy():\n",
" new_list = numpy.empty(len(ints))\n",
" for i in xrange(len(ints)):\n",
" new_list[i] = str(ints[i])\n",
"timeit(new_slow_numpy, \"'Slow' method, with numpy array\")\n",
"\n",
"def new_slow2():\n",
" new_list = []\n",
" for i in xrange(len(ints)):\n",
" new_list.append(str(ints[i]))\n",
"timeit(new_slow2, \"'Slow' method, with append\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Could 'slow' be sped up by using numpy arrays? Probably not, if we keep using the naive loop. But worth a shot! Turns out it's way slower.\n",
"\n",
"I added the `.append` one for fun. I love `.append`! But look at that overhead :("
]
},
{
"cell_type": "code",
"execution_count": 29,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"using basic map function:\n",
" 0.225333372752\n",
"using itertools map function:\n",
" 0.203333218892\n"
]
}
],
"source": [
"import itertools\n",
"\n",
"def itertools_method():\n",
" new_list = [x for x in itertools.imap(str, ints)]\n",
"\n",
"timeit(faster, \"using basic map function\")\n",
"timeit(itertools_method, \"using itertools map function\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"I didn't expect itertools to be faster, since it just uses map underneath. However, it seems to be consistently faster than the one we called 'faster'. That's unexpected! The documenation for the function (https://docs.python.org/2/library/itertools.html#itertools.imap) even says it's the equivalent of what we're doing. It must just be really fast at it."
]
},
{
"cell_type": "code",
"execution_count": 31,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"using itertools with direct conversion:\n",
" 0.180666685104\n"
]
}
],
"source": [
"def itertools_list():\n",
" new_list = list(itertools.imap(str, ints))\n",
" \n",
"timeit(itertools_list, \"using itertools with direct conversion\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Closest one yet! Uses itertools's imap (which returns an iterator, not a list) and tries to convert it immediately. Still slower than 'superfast'"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"This stackoverflow question yields some interesting ideas: http://stackoverflow.com/questions/1247486/python-list-comprehension-vs-map?rq=1\n",
" \n",
"The big takeaway: map (which we've found to be fastest) is only fast when your function is super simple. When it's anything that is more complex than a direct function call, list comprehensions take over."
]
},
{
"cell_type": "code",
"execution_count": 33,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"map with a complex function:\n",
" 0.413666566213\n",
"list comprehensions with a complex function:\n",
" 0.308000008265\n"
]
}
],
"source": [
"def map_complex():\n",
" new_list = map(lambda i: str(i) + \"!\", ints)\n",
" \n",
"def list_comprehensions_complex():\n",
" new_list = [str(i) + \"!\" for i in ints]\n",
" \n",
"timeit(map_complex, \"map with a complex function\")\n",
"timeit(list_comprehensions_complex, \"list comprehensions with a complex function\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"But that wasn't really your question ^_^\n",
"\n",
"So for your specific example, map wins! List comprehensions will usually win, but with your question don't. And `for` loops always lose."
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 2",
"language": "python",
"name": "python2"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 2
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython2",
"version": "2.7.3"
}
},
"nbformat": 4,
"nbformat_minor": 0
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment