Skip to content

Instantly share code, notes, and snippets.

@minrk
Created June 7, 2013 20:16
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save minrk/5732094 to your computer and use it in GitHub Desktop.
Save minrk/5732094 to your computer and use it in GitHub Desktop.
Display the source blob
Display the rendered blob
Raw
{
"metadata": {
"name": "REST demo"
},
"nbformat": 3,
"nbformat_minor": 0,
"worksheets": [
{
"cells": [
{
"cell_type": "heading",
"level": 1,
"metadata": {},
"source": [
"Concurrent REST requests with threads"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"This is a simple demo of using threads for concurrent consumption of a REST API.\n",
"\n",
"First, we define our simple function for processing a single resource ID.\n",
"It has three basic steps:\n",
"\n",
"1. GET the record\n",
"2. parse / process it\n",
"3. PUT to update the record"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"import requests\n",
"\n",
"url_t = \"http://localhost:8000/records/%i\"\n",
"\n",
"def process_id(id):\n",
" \"\"\"process a single ID\"\"\"\n",
" # fetch the data\n",
" r = requests.get(url_t % id)\n",
" # parse the JSON reply\n",
" data = r.json()\n",
" # and update some data with PUT\n",
" requests.put(url_t % id, data=data)\n",
" return data\n",
" "
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 1
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Our dummy webservice is just a simple REST service that serves up the `/usr/share/dict/words` word list:"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"import os\n",
"ip = get_ipython()\n",
"print ip.pycolorize(open(os.path.expanduser(\"~/temp/echo.py\")).read())"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"\u001b[1;34m\"\"\"Simple dummy REST webservice\u001b[0m\n",
"\u001b[1;34m\u001b[0m\n",
"\u001b[1;34mIncludes artificial delay in requests to allow simulation of concurrent access.\u001b[0m\n",
"\u001b[1;34m\"\"\"\u001b[0m\u001b[1;33m\u001b[0m\n",
"\u001b[1;33m\u001b[0m\u001b[1;32mimport\u001b[0m \u001b[0mjson\u001b[0m\u001b[1;33m\u001b[0m\n",
"\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\n",
"\u001b[1;33m\u001b[0m\u001b[1;32mfrom\u001b[0m \u001b[0mtornado\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mhttpserver\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mHTTPServer\u001b[0m\u001b[1;33m\u001b[0m\n",
"\u001b[1;33m\u001b[0m\u001b[1;32mfrom\u001b[0m \u001b[0mtornado\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mioloop\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mIOLoop\u001b[0m\u001b[1;33m\u001b[0m\n",
"\u001b[1;33m\u001b[0m\u001b[1;32mfrom\u001b[0m \u001b[0mtornado\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mweb\u001b[0m\u001b[1;33m\u001b[0m\n",
"\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\n",
"\u001b[1;33m\u001b[0m\u001b[1;32mfrom\u001b[0m \u001b[0mtornado\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0moptions\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mdefine\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0moptions\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mparse_command_line\u001b[0m\u001b[1;33m\u001b[0m\n",
"\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\n",
"\u001b[1;33m\u001b[0m\u001b[0mdefine\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m\"port\"\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mdefault\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;36m8000\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mhelp\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;34m\"run on the given port\"\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mtype\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mint\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\n",
"\u001b[1;33m\u001b[0m\u001b[0mdefine\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m\"delay\"\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mdefault\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;36m0.1\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mhelp\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;34m\"artificial delay for GET requests\"\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mtype\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mfloat\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\n",
"\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\n",
"\u001b[1;33m\u001b[0m\u001b[1;31m# load simple word list, or RESTful data\u001b[0m\u001b[1;33m\u001b[0m\n",
"\u001b[1;33m\u001b[0m\u001b[0mwords\u001b[0m \u001b[1;33m=\u001b[0m \u001b[1;33m[\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m\u001b[0m\n",
"\u001b[1;33m\u001b[0m\u001b[1;32mwith\u001b[0m \u001b[0mopen\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m\"/usr/share/dict/words\"\u001b[0m\u001b[1;33m)\u001b[0m \u001b[1;32mas\u001b[0m \u001b[0mf\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\n",
"\u001b[1;33m\u001b[0m \u001b[1;32mfor\u001b[0m \u001b[0mline\u001b[0m \u001b[1;32min\u001b[0m \u001b[0mf\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\n",
"\u001b[1;33m\u001b[0m \u001b[0mwords\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mappend\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mline\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mstrip\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\n",
"\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\n",
"\u001b[1;33m\u001b[0m\u001b[1;32mclass\u001b[0m \u001b[0mMainHandler\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mweb\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mRequestHandler\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\n",
"\u001b[1;33m\u001b[0m \u001b[1;33m\u001b[0m\n",
"\u001b[1;33m\u001b[0m \u001b[1;33m@\u001b[0m\u001b[0mweb\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0masynchronous\u001b[0m\u001b[1;33m\u001b[0m\n",
"\u001b[1;33m\u001b[0m \u001b[1;32mdef\u001b[0m \u001b[0mget\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0marg\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\n",
"\u001b[1;33m\u001b[0m \u001b[0mindex\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mint\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0marg\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\n",
"\u001b[1;33m\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mwrite\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mjson\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mdumps\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mdict\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mindex\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mindex\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mword\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mwords\u001b[0m\u001b[1;33m[\u001b[0m\u001b[0mindex\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\n",
"\u001b[1;33m\u001b[0m \u001b[1;31m# artificial delay for finish:\u001b[0m\u001b[1;33m\u001b[0m\n",
"\u001b[1;33m\u001b[0m \u001b[0mloop\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mIOLoop\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0minstance\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\n",
"\u001b[1;33m\u001b[0m \u001b[0mloop\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0madd_timeout\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mloop\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mtime\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m \u001b[1;33m+\u001b[0m \u001b[0moptions\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mdelay\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mfinish\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\n",
"\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\n",
"\u001b[1;33m\u001b[0m \u001b[1;32mdef\u001b[0m \u001b[0mput\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0marg\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\n",
"\u001b[1;33m\u001b[0m \u001b[1;34m\"\"\"put does nothing\"\"\"\u001b[0m\u001b[1;33m\u001b[0m\n",
"\u001b[1;33m\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mwrite\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mjson\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mdumps\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mdict\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mstatus\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;34m\"ok\"\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\n",
"\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\n",
"\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\n",
"\u001b[1;33m\u001b[0m\u001b[1;32mdef\u001b[0m \u001b[0mmain\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\n",
"\u001b[1;33m\u001b[0m \u001b[0mparse_command_line\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\n",
"\u001b[1;33m\u001b[0m \u001b[0mapplication\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mweb\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mApplication\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;33m\u001b[0m\n",
"\u001b[1;33m\u001b[0m \u001b[1;33m(\u001b[0m\u001b[1;34mr\"/records/(.*)\"\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mMainHandler\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m\u001b[0m\n",
"\u001b[1;33m\u001b[0m \u001b[1;33m]\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\n",
"\u001b[1;33m\u001b[0m \u001b[0mhttp_server\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mHTTPServer\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mapplication\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\n",
"\u001b[1;33m\u001b[0m \u001b[0mhttp_server\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mlisten\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0moptions\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mport\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\n",
"\u001b[1;33m\u001b[0m \u001b[0mIOLoop\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0minstance\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mstart\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\n",
"\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\n",
"\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\n",
"\u001b[1;33m\u001b[0m\u001b[1;32mif\u001b[0m \u001b[0m__name__\u001b[0m \u001b[1;33m==\u001b[0m \u001b[1;34m\"__main__\"\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\n",
"\u001b[1;33m\u001b[0m \u001b[0mmain\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
"\n"
]
}
],
"prompt_number": 2
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Now fetch some answers from the service (it should take a bit more than N/10 seconds, since we are using an artificial delay of 100ms)."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"%time answers = [ process_id(n) for n in range(32) ]\n",
"answers"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"CPU times: user 116 ms, sys: 16.2 ms, total: 133 ms\n",
"Wall time: 3.41 s\n"
]
},
{
"metadata": {},
"output_type": "pyout",
"prompt_number": 3,
"text": [
"[{u'index': 0, u'word': u'A'},\n",
" {u'index': 1, u'word': u'a'},\n",
" {u'index': 2, u'word': u'aa'},\n",
" {u'index': 3, u'word': u'aal'},\n",
" {u'index': 4, u'word': u'aalii'},\n",
" {u'index': 5, u'word': u'aam'},\n",
" {u'index': 6, u'word': u'Aani'},\n",
" {u'index': 7, u'word': u'aardvark'},\n",
" {u'index': 8, u'word': u'aardwolf'},\n",
" {u'index': 9, u'word': u'Aaron'},\n",
" {u'index': 10, u'word': u'Aaronic'},\n",
" {u'index': 11, u'word': u'Aaronical'},\n",
" {u'index': 12, u'word': u'Aaronite'},\n",
" {u'index': 13, u'word': u'Aaronitic'},\n",
" {u'index': 14, u'word': u'Aaru'},\n",
" {u'index': 15, u'word': u'Ab'},\n",
" {u'index': 16, u'word': u'aba'},\n",
" {u'index': 17, u'word': u'Ababdeh'},\n",
" {u'index': 18, u'word': u'Ababua'},\n",
" {u'index': 19, u'word': u'abac'},\n",
" {u'index': 20, u'word': u'abaca'},\n",
" {u'index': 21, u'word': u'abacate'},\n",
" {u'index': 22, u'word': u'abacay'},\n",
" {u'index': 23, u'word': u'abacinate'},\n",
" {u'index': 24, u'word': u'abacination'},\n",
" {u'index': 25, u'word': u'abaciscus'},\n",
" {u'index': 26, u'word': u'abacist'},\n",
" {u'index': 27, u'word': u'aback'},\n",
" {u'index': 28, u'word': u'abactinal'},\n",
" {u'index': 29, u'word': u'abactinally'},\n",
" {u'index': 30, u'word': u'abaction'},\n",
" {u'index': 31, u'word': u'abactor'}]"
]
}
],
"prompt_number": 3
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Now we define a function that calls our single-id function for a range of IDs.\n",
"Simple enough."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"def process_id_range(id_range, store=None):\n",
" \"\"\"process a number of ids, storing the results in a dict\"\"\"\n",
" if store is None:\n",
" store = {}\n",
" for id in id_range:\n",
" store[id] = process_id(id)\n",
" return store"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 4
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"This does the same thing as the list comprehension above (but with a dict)\n",
"in a single function call:"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"%time s = process_id_range(range(32));\n",
"s"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"CPU times: user 118 ms, sys: 15.6 ms, total: 134 ms\n",
"Wall time: 3.42 s\n"
]
},
{
"metadata": {},
"output_type": "pyout",
"prompt_number": 5,
"text": [
"{0: {u'index': 0, u'word': u'A'},\n",
" 1: {u'index': 1, u'word': u'a'},\n",
" 2: {u'index': 2, u'word': u'aa'},\n",
" 3: {u'index': 3, u'word': u'aal'},\n",
" 4: {u'index': 4, u'word': u'aalii'},\n",
" 5: {u'index': 5, u'word': u'aam'},\n",
" 6: {u'index': 6, u'word': u'Aani'},\n",
" 7: {u'index': 7, u'word': u'aardvark'},\n",
" 8: {u'index': 8, u'word': u'aardwolf'},\n",
" 9: {u'index': 9, u'word': u'Aaron'},\n",
" 10: {u'index': 10, u'word': u'Aaronic'},\n",
" 11: {u'index': 11, u'word': u'Aaronical'},\n",
" 12: {u'index': 12, u'word': u'Aaronite'},\n",
" 13: {u'index': 13, u'word': u'Aaronitic'},\n",
" 14: {u'index': 14, u'word': u'Aaru'},\n",
" 15: {u'index': 15, u'word': u'Ab'},\n",
" 16: {u'index': 16, u'word': u'aba'},\n",
" 17: {u'index': 17, u'word': u'Ababdeh'},\n",
" 18: {u'index': 18, u'word': u'Ababua'},\n",
" 19: {u'index': 19, u'word': u'abac'},\n",
" 20: {u'index': 20, u'word': u'abaca'},\n",
" 21: {u'index': 21, u'word': u'abacate'},\n",
" 22: {u'index': 22, u'word': u'abacay'},\n",
" 23: {u'index': 23, u'word': u'abacinate'},\n",
" 24: {u'index': 24, u'word': u'abacination'},\n",
" 25: {u'index': 25, u'word': u'abaciscus'},\n",
" 26: {u'index': 26, u'word': u'abacist'},\n",
" 27: {u'index': 27, u'word': u'aback'},\n",
" 28: {u'index': 28, u'word': u'abactinal'},\n",
" 29: {u'index': 29, u'word': u'abactinally'},\n",
" 30: {u'index': 30, u'word': u'abaction'},\n",
" 31: {u'index': 31, u'word': u'abactor'}}"
]
}
],
"prompt_number": 5
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"And finally the real point of this whole exercise,\n",
"we can partition a list of IDs and assign sub-lists to threads,\n",
"so that we can have some requests running concurrently."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"from threading import Thread"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 6
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"def threaded_process(nthreads, id_range):\n",
" \"\"\"process the id range in a specified number of threads\"\"\"\n",
" store = {}\n",
" threads = []\n",
" # create the threads\n",
" for i in range(nthreads):\n",
" ids = id_range[i::nthreads]\n",
" t = Thread(target=process_id_range, args=(ids,store))\n",
" threads.append(t)\n",
" \n",
" # start the threads\n",
" [ t.start() for t in threads ]\n",
" # wait for the threads to finish\n",
" [ t.join() for t in threads ]\n",
" return store\n"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 7
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"If we test this, we will see that adding threads allows this to complete faster.\n",
"Given the nature of the dummy workload, this should actually scale to almost 100 threads."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"import time"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 8
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"id_range = range(100)\n",
"tic = time.time()\n",
"reference = process_id_range(id_range)\n",
"reftime = time.time() - tic\n",
"print 1, reftime\n",
"\n",
"nlist = [1,2,4,8,16,32,64]\n",
"tlist = [reftime]\n",
"for nthreads in nlist[1:]:\n",
" tic = time.time()\n",
" ans = threaded_process(nthreads, id_range)\n",
" toc = time.time()\n",
" print nthreads, toc-tic\n",
" assert ans == reference\n",
" tlist.append(toc-tic)"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"1 10.8778159618\n",
"2"
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
" 5.70237803459\n",
"4"
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
" 3.02138209343\n",
"8"
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
" 1.79273200035\n",
"16"
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
" 1.00950598717\n",
"32"
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
" 0.682367086411\n",
"64"
]
},
{
"output_type": "stream",
"stream": "stdout",
"text": [
" 0.624274015427\n"
]
}
],
"prompt_number": 9
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"%pylab inline"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"\n",
"Welcome to pylab, a matplotlib-based Python environment [backend: module://IPython.kernel.zmq.pylab.backend_inline].\n",
"For more information, type 'help(pylab)'.\n"
]
}
],
"prompt_number": 10
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"plt.loglog(nlist, [ len(id_range) / t for t in tlist], '-o')\n",
"plt.xlabel(\"n threads\")\n",
"plt.ylabel(\"requests / sec\");"
],
"language": "python",
"metadata": {},
"outputs": [
{
"metadata": {},
"output_type": "display_data",
"png": "iVBORw0KGgoAAAANSUhEUgAAAm4AAAGOCAYAAAAuBI8MAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJzt3Xt81PWd7/H3JJPJdRKScA23GCAECIhBEAIYaEDBViWt\nXbsIgtb1US/VPXtKq0dsu8Vz9Jyt7amtBfs4u8pF6BYslO1uCfeUFWqxsOViTDAJYEQC5Da5Zybz\nO38Epk4JChjmN9/k9fzHzEwuH3no8Mrv8v06LMuyBAAAgLAXYfcAAAAAuDqEGwAAgCGcdg/QlfPn\nz+vXv/61JGnSpEm69dZbbZ4IAADAfo5wvsato6NDGzZs0KJFi+weBQAAwHZhe6q0oqJCL7zwgmbM\nmGH3KAAAAGEhrI+4tbe3a926dXr44YftHgUAAMB2IbvGzefzaf369SouLtaLL74YeH7r1q06ePCg\nJCknJ0cFBQUqKSnRiBEj5HK5QjUeAABA2AtZuG3YsEHZ2dkqLi4OPFdcXKyKigqtWLFCkrRy5Uod\nPXpU8fHxevXVV5WQkKDJkyeHakQAAICwFvJTpc8++2zgiNv69es1YcIEZWdnS5JKS0t14MABLVmy\nJJQjAQAAGMHWmxMaGhrkdrsDjxMTE1VfX2/jRAAAAOHL1nBzu93yeDyBxx6PR4mJiTZOBAAAEL5s\nXYA3JydHhYWFGj9+vCRp9+7dmj59+jV9j127dt2I0QAAAG6I/Pz86/5aW8MtKytLJSUlWr58uaTO\nkLsUcdciJyenu0cD0Mv927/9m+6++267xwDQwxw6dOhzfX3Iw+2TS4FI0r333qt777031GMAAAAY\nJ2x3TgAAAEAwwg0AAMAQhBsAAIAhCDcA6EJmZqbdIwDAZQg3AOjC6NGj7R4BAC5DuAEAABiCcAMA\nADAE4QYAAGAIwg0AAMAQhBsAAIAhCDcAAABDEG4AAACGINwAAAAMQbgBAAAYgnADAAAwBOEGAABg\nCMINAADAEIQbAACAIQg3AAAAQxBuAAAAhiDcAAAADEG4AQAAGIJwAwAAMAThBgAAYAjCDQAAwBCE\nGwAAgCEINwAAAEMQbgAAAIYg3AAAAAxBuAEAABiCcAMAADAE4QYAAGAIwg0AAMAQhBsAAIAhCDcA\nAABDEG4AAACGINwAAAAMQbgBAAAYgnADAAAwBOEGAABgCMINAADAEIQbAACAIQg3AAAAQxBuAAAA\nhiDcAAAADEG4AQAAGIJwAwAAMAThBgAAYAjCDQAAwBCEGwAAgCEINwAAAEMQbgAAAIYg3AAAAAxB\nuAEAABiCcAMAADAE4QYAAGAIwg0AAMAQhBsAAIAhCDcAAABDEG4AAACGINwAAAAMQbgBAAAYgnAD\nAAAwBOEGAABgCMINAADAEIQbAACAIQg3AAAAQxBuAAAAhiDcAAAADEG4AQAAGIJwAwAAMAThBgAA\nYAjCDQAAwBCEGwAAgCEINwAAAEMQbgAAAIYg3AAAAAxBuAEAABiCcAMAADAE4QYAAGAIwg0AAMAQ\nhBsAAIAhCDcAAABDEG4AAACGINwAAAAM4bR7AAAAgEt2Fu3Tms3b5JNDTll6sGCe5uTNtHussEG4\nAQCAsLCzaJ9eWr1FEbmLAs+9tHqdJBFvF3GqFAAAhIU1v/5dULRJUkTuIq3dss2micIPR9wAAMB1\nsyxL3g5Lzd4ONXv9am6/+E9vh1q8HWpu9wdea/F2qKm9Qy0XX//La53PlZxtVtr4y3+G13KE/l8s\nTBFuAAD0Qu0d/s6AumJo/VV0tXdcIc78cjikuKhIxUVFKDYqUvGuzn9eei7O1fnPfvEupSdHKjYq\nIui1S4+feDdOVV3MGuWwQv7nE64INwAAPodQXkzvvRRbXQXUJz5ubr94dOtiWDUHvdb5nCV9RmhF\nKs7VGVuxn4ivuKjIwNd0fhyhqMjuufJqyZfn66XV64JOl/rfXqvFSwu65fv3BIQbAADX6Woupvf5\nrUAsffJIVos3OKb+Orq6ijO/3wpE1aWYir8YX58Mq5Q4p+Jc0VcMrThXpFzdFFvd6dKf2dotm+S1\nHIpyWFq8tIAbEz6BcAMA4Dq98VbXF9N/e9Vqjfywj5q9HfL5rcDRq9ioSMV/Ip7+ElYR6hPrVFpi\ndNCpxU9GV2xUpFyRDjkcPft6rzl5Mwm1T0G4AQBwlS40tetYVZOOn23U8aomHTnXooFdfN5NqXFa\n9eUsxbkiFd0LYguhQ7gBANAFv2XpVG2rjl2MtONVTWrxdih7YILGDojXkyNS1LA3tsuL6ROiHEqJ\niwr5zOj5CDcAACS1+fwqOd8ZaMfONqn4XJOSYpwaNyBeE9PcWnjLQA1Nig46esbF9Ag1wg0A0CvV\ntXgDR9KOVzWqvKZV6ckxyh6QoPmjU/WtvGFKjv30o2ZcTI9QI9wAAD2eZVn6yNOmY2c7I+14VZNq\nW3wa2z9OYwck6OHJaRrdL14xzmu/05KL6RFKhBsAoMfxdvj1QXWLjlc1Xoy1JkU7HRo3IEHjBsSr\nILu/hveJUWQENw3ALIQbAMB4jW0+vXfuL9ennbjQrLTEaGUPjNesjGQ9Pm2I+ie47B4T+NwINwCA\nUSzL0rlGr45dPOV5/Gyjzja2K7NvnLIHJuhvJw7QmP7xindF2j0q0O0INwBAWOvwW6qoaelcP62q\nUcfPNqnDspQ9oHNZjjszUzQiNU5OTnuiFyDcAABhpcXboffPNXden1bVpPfPNalvvEvjBsRr8pBE\nPXRrmga5XSxqi14pLMOtpqZG69atU3x8vMaMGaPc3Fy7RwIA3CDVzd7AkbRjVY06XdemEamxyh4Q\nrwVj+2ns7HQlxoTlX1dAyIXl/wkej0cPPPCAUlNTtWbNGsINAHoIv2Xpw7rWoG2jGts7NHZAvLIH\nJOixqUOU2TdOrutYlgPoDcIy3NLT0yVJZ86cUWxsrL3DAACuW7vPr9ILzYHr096ralKCK1LZAxM0\nbmCC7r95gIb2iVEEpz2BqxKW4SZJtbW12rx5sx599FG7RwEAXCVPqy+wE8GxqiaVVbdoeJ8YjRsQ\nr7mjUvT3M4YplT08gesWsnDz+Xxav369iouL9eKLLwae37p1qw4ePChJysnJUUFBgZqamrR+/Xo9\n9NBDiorif3AACEeWZemMpz2wE8HxqiZdaGpXVv94ZQ+I15KcQcrqH6fYKJblALpLyMJtw4YNys7O\nVnFxceC54uJiVVRUaMWKFZKklStX6ujRo4GQe+utt+R2u7VgwYJQjQkAuAKf31JZdbOOnW3Se1Wd\nNxJEOhwaN7Dz+rS7x/TVTSmx7EYA3EAhC7fFixdLkjZu3Bh47vDhw8rPzw88zs/P14EDB/Twww+H\naiwA6HV2Fu3Tms3b5JNDTll6sGBel3ttNrV3qPhck45dvImg9EKzBia4NG5ggnLTk/TobYPVPyGK\nZTmAELL1GreGhga53e7A48TERNXX19s4EQD0bDuL9uml1VsUkbso8NxLq9dJkiZMui1w2vPY2Sad\n8bQps1+cxg2I11cnDNDY/nFKiA7bS6OBXsHW/wPdbrc8Hk/gscfjUWJioo0TAUDPtmbztqBok6SI\n3EVatvINjfxSH40bEK/sgfHKH5mikamxiopkWQ4gnNgabjk5OSosLNT48eMlSbt379b06dPtHAkA\neizLstTgtbp8LaNvvH71QDanPYEwZ2u4ZWVlqaSkRMuXL5fUGXKXIg4A0D1O17aqqKJWe8tqdfJC\nk/p18TkJUQ6iDTCAw7Ksrn/9MsSuXbuUk5Nj9xgAEFbOeNpUVN4Zaw1tHbo9o49mZSTrw/f+pP+9\n5jdBp0v9b6/VM0sLurxBAUD3OnToUNCNmdeKq0wBoIc419jeGWvltTrf6NXtGX305PShGjcgPrAz\nQVb/2+VwOLR2yyZ5LYeiHJYWE22AMQg3ADBYdbNX+ypqtbe8TpV1rZqe3kePTB6sCYMSrrie2py8\nmYQaYCjCDQAMU9fi1X+erFdRea3Kqls0bXiSFk4coFvS3NwFCvRwhBsAGKChzae3L8ba++ebNXlI\nohaM66fJQxLlchJrQG9BuAFAmGpu79CB0/XaW16rox83KmewW/NGp+p7c25SDPt/Ar0S4QYAYaTV\n59cfL8baoY8aNH5QgmZlJOuZWemKdxFrQG9HuAGAzdo7/Hq30qO9ZXU6WOlRVr845WUk67/NHCY3\nW0wB+ATeEQDABj6/pUMfNaiovFZ/OF2vm1JiNSsjWY9PG6w+sVF2jwcgTBFuABAiHX5LRz5uVFF5\nrf7zZJ2GJMVo1og+evjWNKXGE2sAPhvhBgA3kN+ydLyqSUXltdpXUae+8VHKy0jWqwuyNMDtsns8\nAIYh3ACgm1mWpZLzzdpbXqvfl9fJHR2pvIxk/ehLmRqcFG33eAAMRrgBQDewLEvlNS3aW9a5i4Er\n0qG8jGS9OH+EhifH2j0egB6CcAOAz+FUbYuKyuu0t7xWPr+lvIxkfX/uTcpIiZXD0fWWUwBwvQg3\nALhGH9W3BTZzb2zrUF5Gsr6dN1yj+8URawBuKMINAK5CVUO7iipqVVRWqwvNXt1+Ux89NX2oxg6I\nVwSxBiBEgsKtoaFBkZGRiouLkyQ1NTXJsiwlJCTYMhwA2Km6yavfV9SqqLxOlfWtmpHeR39322CN\nH5igyAhiDUDoBYXbv/zLvyg/P1/Z2dmSpLKyMu3Zs0dPP/20LcMBQKjVtXi1r6JORRV1qqhp0dRh\nSVp4y0DlDHbLSawBsFlQuJ09ezYQbZI0YcIEbdq0KeRDAUAoeVp92n+qc3/QkvPNmjI0UV/O7qdb\nByfK5YywezwACAgKt6ioy1fu5kJbAD1RU3uHDpyqV1F5rY6ebdSkwYm6a3Sqvj83QzHEGoAwFRRu\nQ4cO1X/8x3/orrvukiRt27ZNQ4YMsWUwAOhurd4OvfOhR3vLa3X4owZNGJSgWSOS9ezsdMW5Iu0e\nDwA+U1C4LVy4UD//+c+1ZcsWSdKoUaP0+OOP2zIYAHSHdp9fBys7Y+3dygaN6R+nvIxk/cPMYXJH\nc2M9ALMEvWvFx8dr2bJlamtrk2VZiomJsWsuALhu3g6/Dp9p0N6yWv3htEcjUmM1KyNZT0wboj6x\nbOYOwFyX/bp55MgRlZeXa8GCBbpw4YL69u1rx1wAcE06/Jb+/HGDisrr9PbJOg3pE6NZGcn6+pTB\nSo0j1gD0DEHhtnPnTpWUlKiyslILFizQb37zG/Xv31933323XfMBgHYW7dOazdvkk0NOWXqwYJ7m\n5M2U37J07GyTisprta+iTv0TXMrL6KOfF2Spf4LL7rEBoNsFhdv+/fu1fPlyrVixQpK0ZMkSPf/8\n84QbANvsLNqnl1ZvUUTuosBzK/55rX73/gWdcY9SUkyk8jKS9X/vyVRaYrSNkwLAjRcUbg6HQxER\nf7kN3ul0yuXit1YA9lmzeVtQtElS9O2LdeTAm/rnH87XsGSuxQXQewSFW2RkpFpaWgKPy8vL5XRy\n1xWA0Gvv8Ou/zjTqZH27ukqzfu4Yog1ArxNUZffdd59eeeUVXbhwQa+//rr++Mc/atmyZXbNBqCX\naWjz6Y8fenTgVL3+9FGDbkqOUUyE1eXnRjm6fh4AerKgcMvMzNQjjzyiQ4cOyeFwaMGCBUpOTrZr\nNgC9wLnGdh04Va/9p+pVcr5JEwYlKHd4Hz2Z27l0x87Ee/XS6nVBp0v9b6/V4qUFNk4NAPYICjef\nz6ekpCTNnTtXFRUVOnr0qKZOncp1bgC6jWVZKq9p1YFTddp/ql7nGtt127Ak3TO2ryYNvkkxUcE7\nGMzJmylJWrtlk7yWQ1EOS4uXFgSeB4DeJCjcVq5cqalTpyojI0M//vGPNXbsWP35z3/WN7/5Tbvm\nA9ADdPgtHatq1P6TnUfWHA4pd3iSvjF1sMYNSFBkxKfviTwnbyahBgD6q3CrqqrS5MmTtXPnTs2Z\nM0f33HOPnn/+ebtmA2CwVm+H3q1s0P5Tdfrjhx4NcLuUO7yPfnBHhtKTY+RwfHqsAQAud9lyIJZl\n6ciRI1qwYIEkqbW11ZbBAJintsWrP5yq1/7T9Tr6caOy+scrd3iSlt6axoK4ANANgsJtypQpeuyx\nxzRo0CBlZGRoz549GjlypF2zATBAZX2r9l+8ueBUbatuHezWF0Yk6zt5w5XAJu4A0K0clmUF3VPf\n3NysuLg4SVJjY6NiYmLCei23Xbt2KScnx+4xgF7Db1kqOd98Mdbq1Nzu17ThScodnqQJgxLkioz4\n7G8CAL3UoUOHlJ+ff91ff1mRXYo2SUpISLjubwyg57i0GO7+U3X6w6l6uaOdyk1P0rLbhyuzX5wi\nuF4NAEIifA+lAbDVpcVw95+q16GLi+FOG56kl780SoOT2LEAAOxAuAEIONfYrv2n6nXg4mK4Nw9y\na9rwJH3z4mK4AAB7OXft2qXp06crJobfoIHe5q8Xwz3f5NWUoYlXXAwXAGAvZ1tbm773ve9p3Lhx\nuuuuu9S3b1+7ZwJwA3X4LR092xjYZirCIU0bnqRvTB2icQPiP3MxXACAfZx33XWX5s2bp3fffVev\nvvqqEhMT9cUvflGZmZl2zwagm7R4O/QnFsMFAOM5JSkiIkJTpkzRlClTVF5ert/+9rd68803NW/e\nPE2dOpU3dcBAgcVwT9Xr6FkWwwWAnuCymxMyMjL01FNPqaamRr/73e+0ZcsWLV++XG632475AFyD\nyvrWzv1AT19cDHeIW18YmazvzGIxXADoCa74Tp6SkqIHHnhA9913n6Kjo0M5E4CrdKXFcBfdMpDF\ncAGgB/rMX8GJNiC8tPv8+q+PG7T/VH3nYrgxTuUOT9K384ZrVF8WwwWAnoxzJ4ABuloMNzc9SS9/\nKVODk/jlCgB6C8INCFOXFsPdf6pOpeebWQwXABAcbufOnZPL5VKfPn20fft2lZWVqaCgQAMHDrRr\nPqDXuLQY7v5TdTpwcTHc24Ym6t6x/TRpsJvFcAEAweG2atUq3Xfffaqrq9OePXs0f/58/eIXv9B3\nv/tdu+YDejQWwwUAXIugcOvo6NDYsWO1detWzZ07V7fffrt27dpl12yAsXYW7dOazdvkk0NOWXqw\nYJ7m5M2U1LkY7ruVDTpwqk7vfOjRIHe0pg1P0oo7MjScxXABAJ/ismvcPvroI73zzjt6+umn1d7e\nrsbGRjvmAoy1s2ifXlq9RRG5iwLP/a/X1+rdSo+a+mYFLYb70OQ09YtnMVwAwNUJCrevfOUr+ulP\nf6qcnBz1799fO3fuVH5+vl2zAUZas3lbULRJknPGYv22cK1WfG8ai+ECAK5b0N8eMTExeumllwKP\n8/PzVVpaGvKhAFO1+fy60NLR5WvDUuI0e0RKiCcCAPQkQcuqb9iwIehFh8OhX//61yEdCDCNZVl6\n/1yTXnn7Qy3ccEy1Ta1dfl6UwwrxZACAnsYpSe+9956OHz+uc+fOadOmTbKszr9gWltbVVtba+uA\nQLiqbvZq14kabT9RI5/f0h2jUrSyIEtHhn1FL61eF3S61P/2Wi1eWmDjtACAnsApSXFxcerXr59c\nLpf69u0beNHlcumee+6xbTgg3LR3+PWH0/XaUVqj41VNmp6epL+fMVTjBsQH7ga9dPfo2i2b5LUc\ninJYWry0IPA8AADXyylJ6enpSk9PV1VVlWbNmmXzSEB4sSxLH1S3aHtpjfaW1yo9OUZ3ZKbquS+k\nX3FR3Dl5Mwk1AEC3C7o5Yfbs2aqrq2PnBEBSXYtXu8tqtb20Wk3tft2RmaKf3pupgW72BgUA2CPo\n5oRVq1bpzJkzOnnypPbs2aNx48bpF7/4hV2zASHn81s6cKpe399Rroc2FuuDC836xtQhWn3/WC3O\nGUS0AQBsxc4JgKSTNS0qLK3R7rIapSVG687MVC3LG654F/uDAgDCBzsnoNfytPq0t7xWhaXVqm32\naW5min70pVEanBRj92gAAHSJnRPQq3T4Lf3powZtL63Wnz5q0OQhiXr41jRNTHOzoTsAIOwFhduE\nCRM0YcKEwOM5c+aEfCDgRviwrlXbS6u184Na9Y2P0p2ZqXp6xlC52XoKAGCQoL+1vF6vNm3apMrK\nSi1btkyHDh3S2LFjFRPDqSOYp6m9Q3vLa7WjtEZnG9qUPypFL84fofTkWLtHAwDgugSF25tvvqlh\nw4apuLhYklRVVaV3331Xjz76qC3DAdfKb1n6rzMN2l5ao3c+9Cgnza2vTRygyUMSORUKADBeULhV\nVlZq6dKl2rdvnyRp/vz5eu6552wZDLgWZzxt2nGiRjtOVCsx2qk7MlP02LQhSorhVCgAoOcI+lvt\n0h6lnxQREXHZc0A4aPF26PcVddpeWqPTda3KH5msf5w7QiNSORUKAOiZgsItKSlJZ86cCTzesWOH\n+vXrF/KhgCuxLEtHzzZqe2mN9p+q1/iBCfpydj9NGZqoqEh+yQAA9GxB4bZo0SK99tprOn36tJYt\nW6bo6GgtW7bMrtmAgKqGdu38oEbbS6vlckbozswUfX1KmpJjo+weDQCAkAkKt5SUFD3zzDP6+OOP\nJUmDBg2Sw8EF3bBHq8+vt092ngotq25WXkaynvvCTRrVN5b/LgEAvdJlV247HA6lpaUFHvv9fq5z\nQ8hYlqXic83aXlqtfSfrlNUvTndlpWrasAy5nPx3CADo3YLCbfHixYEjGe3t7bIsS3FxcXr99ddt\nGQ69x4Wmdu38oFY7SqtlSbojM1WvfTlLfeNddo8GAEDYCAq3tWvXBj72+Xz693//d8XFxYV8KPQO\n7T6/Dpyu1/bSar1/vlkz0/vov98+XGP6x3EqFACALlxxkSun06l7771XL7zwgubOnRvKmdCDWZal\nExdaVFharaLyWo1IjdMdmSl6fk6GYjgVCgDAp/rU1Un9fr88Hk+oZkEPVtvi1a4ParS9tEZtPr/u\nyEzVqwuyNMDNqVAAAK5WULht3Lgx8LHP59P777+vMWPGhHwo9AzeDr/++KFHhaXVOna2SbnDk/Rk\n7hBlD0xQBKdCAQC4ZkHh9snFdiMiInTLLbcoKysr5EPBbGXVLdpeWq3dZbUa1idGd2am6NnZ6YqN\nirR7NAAAjBYUbrNmzbJpDJiuvtWnPWWdp0I9bT7NHZWqn9yTqbTEaLtHAwCgxwgKt5///OdyOByB\nPUs/+fGlx4899lhoJ0TY6vBbOljp0Y7SGh0606DbhibqkSlpmpjm5lQoAAA3QFC4ZWRkaM+ePfrq\nV78qv9+vt956S7Nnz9awYcNkWRZLNECSdKq2RdtP1GjXiRoNdEdrbmaK/uH2YYp3cSoUAIAbKSjc\nDh8+rGeeeUbJycmSpJEjR+q1117TvHnzbBkO4aOhzaei8joVllbrQpNXc0al6P98cZSG9YmxezQA\nAHqNoHBraWkJRJvUuXdpS0tLyIdC6O0s2qc1m7fJJ4ecsvRgwTzNnjlDh880aHtpjQ5WenTrYLcW\n5wzSpMFuRUZw9BUAgFC7bB23T54S9fv9Qde4oWfaWbRPL63eoojcRYHnnvvFG+pTdEqjJkzWHZkp\nejJ3iBJjPnXZPwAAcIMFLVU/YcIEvfHGG2pra1Nra6tWr16tiRMn2jUbQmTN5m1B0SZJSbOXKunc\ncf1swWjdM7Yf0QYAQBgICrcFCxYoOjpajz/+uJ544gnFxcWpoKDArtlwg1mWpeNnG1VR197l604n\nNxsAABBOgg6jOJ1OLVy4UAsXLrRrHoRAdbNXu07UqLC0WpIUG9n16fAoB6fJAQAIJ0FH3LxerzZs\n2KB/+qd/kiQdOnRIra2ttgyG7uXzW3r7ZJ2+u71Mf7epWJWeNv3D7cP0/+4bo28/eK/8+9cFfb7/\n7bVavIC7iQEACCdBR9zefPNNDRs2TMXFxZKkqqoqvfvuu3r00UdtGQ6f3+naVhWWVmvnBzUanBit\neaNTL9t+ak7eTEnS2i2b5LUcinJYWry0IPA8AAAID0HhVllZqaVLl2rfvn2SpPnz5+u5556zZTBc\nv6b2Dv2+vFbbSqtV1diuuaNS9fKXRmlI0pXXXJuTN5NQAwAgzAWFW1dLf0RERFz2HMKPZVk6VtWk\nbSXV2n+qXhPTEvS3Ewdq8pBE1lwDAKCHCAq3pKQknTlzJvB4x44d6tevX8iHwtW70NSunSdqtK20\nRlERDs0bnaq/m5KmPrFRdo8GAAC6WVC4LVq0SK+99ppOnz6tZcuWKTo6WsuWLbNrNlyBt8Ovd057\nVFharffONWnmTX30zKzhGt0vjv1kAQDowYLC7fjx43r22WcDR93S0tJsGQpdO1nbosKSGu36oEbD\nkmN0Z2aqnvtCumKiWG8NAIDeICjcCgsLNXPmTIItjDS1d2hvWeeNBheavLojM0U/vjtTg5Oi7R4N\nAACEWFC4TZgwQTt27NCcOXM45WYjv2Xp6NlGFZZU68Bpj3LS2NwdAAD8Vbjt3r1bdXV1ev311+V0\ndr7kcDi0evVqW4brbc43tWtHaeeOBtHOCM0bnapHbxvMjQYAAEDSX4XbqlWr7Jqj12rv8OsPp+tV\nWFKt9883Ky8jWf/jC+nK7MuNBgAAIJjzsz8FN0J5TYsKS6q1u6xW6ckxmjc6Vc/PyVCMk3XzAABA\n1wi3EGps82lPWa0KS2tU2+LV3FEpeuWeTA1K5EYDAADw2Qi3G8xvWTrycaO2lVTrnQ89unWwW0tv\nHaRb0rjRAAAAXBvC7QY519iu7aXVKiytUbyr80aDx6cNUWIMf+QAAOD6UBHdqN3n1/6LNxqUXmjW\nrIxkfXfOTRqZGsuNBgAA4HMj3LpBWXWztpXUaE9ZjUamxunO0Sn6/twMRXOjAQAA6EZhH2579+7V\nkSNH9NRTT9k9SpCGNp92f1CrwtJqedp8ujMzVT9bMFoD3dxoAAAAboywDre2tjY5nU4lJSXZPYqk\nzhsNDp9pUGFJjQ5WejR5SKK+PiVNt6S5FcGpUAAAcIOFdbhFR0drxowZKisrs3WOsw1t2nGic0eD\nxGin5o1O1ZO53GgAAABCi/K4gjafX/tP1WlbSY3Kqps1e0SKvj8nQyP7xtk9GgAA6KVCHm4+n0/r\n169XcXGLqoK/AAALY0lEQVSxXnzxxcDzW7du1cGDByVJOTk5KigoCPVosixLJ6o7dzTYW16rzL5x\nmp+VqtxhGXJxowEAALBZyMNtw4YNys7OVnFxceC54uJiVVRUaMWKFZKklStX6ujRoxo/fnxIZvK0\n+rS7rEbbSmrU1N6hOzNTtLIgS/0TXCH5+QAAAFcj5OG2ePFiSdLGjRsDzx0+fFj5+fmBx/n5+Tpw\n4EAg3JYsWdLtc3T4O2802FZSrT991KDbhibqG1MHa8KgBG40AAAAYSksrnFraGiQ2+0OPE5MTFR9\nff0N+Vkfe9pUWFqtHSdqlBwbpTszU/T0jKFyR4fFHwUAAMAVhUWtuN1ueTyewGOPx6PExMRu+/5t\nPr/+82SdtpVU62Rtq74wIlk/uGOERqTGdtvPAAAAuNHCItxycnJUWFgYODW6e/duTZ8+/XN9T8uy\nVHqhWYWlNSoqr1VWvzjdPbavpg5LkiuSGw0AAIB5wiLcsrKyVFJSouXLl0vqDLlruTHhwb9/Tg8W\nzNOcvJmqa/Fqd1mtCkuq1erz687MVG40AAAAPYLDsizL7iE+j127dumZQw61FK1R5qRc1aSM1rRh\nibpzdKrGD+RGAwAAED4OHToUdEPmtQqLI27dITbvQX38zgZtfPXLindF2j0OAABAt+tRF3v1iXcR\nbQAAoMfqUeEW5TD6rC8AAMCn6jHh5n97rRYvmGf3GAAAADdMj7jGbdDxTVq8tEBz8mbaPQoAAMAN\n0yPCbfWP/6fdIwAAANxwPeZUKQAAQE9HuAEAABiCcAMAADAE4QYAAGAIwg0AAMAQhBsAAIAhCDcA\nAABDEG4AAACGINwAAAAMQbgBAAAYgnADAAAwBOEGAABgCMINAADAEIQbAACAIQg3AAAAQxBuAAAA\nhiDcAAAADEG4AQAAGIJwAwAAMAThBgAAYAjCDQAAwBCEGwAAgCEINwAAAEMQbgAAAIYg3AAAAAxB\nuAEAABiCcAMAADAE4QYAAGAIwg0AAMAQhBsAAIAhCDcAAABDEG4AAACGINwAAAAMQbgBAAAYgnAD\nAAAwBOEGAABgCMINAADAEIQbAACAIQg3AAAAQxBuAAAAhiDcAAAADEG4AQAAGIJwAwAAMAThBgAA\nYAjCDQAAwBCEGwAAgCEINwAAAEMQbgAAAIYg3AAAAAxBuAEAABiCcAMAADAE4QYAAGAIwg0AAMAQ\nhBsAAIAhCDcAAABDEG4AAACGINwAAAAMQbgBAAAYgnADAAAwBOEGAABgCMINAADAEIQbAACAIQg3\nAAAAQxBuAAAAhiDcAAAADEG4AQAAGIJwAwAAMAThBgAAYAjCDQAAwBCEGwAAgCEINwAAAEMQbgAA\nAIYg3AAAAAxBuAEAABiCcAMAADAE4QYAAGAIwg0AAMAQhBsAAIAhCDcAAABDEG4AAACGINwAAAAM\nQbgBAAAYgnADAAAwBOEGAABgCMINAADAEIQbAACAIQg3AAAAQxBuAAAAhiDcAAAADEG4AQAAGIJw\nAwAAMAThBgAAYAjCDQAAwBCEGwAAgCEINwAAAEMQbgAAAIYg3AAAAAzhtHuArtTV1Wn9+vVyOp2a\nMWOGxo4da/dIAAAAtgvLcNu+fbseeughxcbG6vXXXyfcAAAAFKanSltbWxUbGytJcjrDsi0BAABC\nLizDDQDsVlJSYvcIAHCZkB3O8vl8Wr9+vYqLi/Xiiy8Gnt+6dasOHjwoScrJyVFBQYGio6PV0tKi\n2NhYeb3eUI0IAAGlpaUaPXq03WMAQJCQhduGDRuUnZ2t4uLiwHPFxcWqqKjQihUrJEkrV67U0aNH\nNXfuXL3xxhtyOp2aNm1aqEYEAAAIayELt8WLF0uSNm7cGHju8OHDys/PDzzOz8/XgQMHNH78eD32\n2GOhGg0AAMAItl7j1tDQILfbHXicmJio+vp6GycCAAAIX7aGm9vtlsfjCTz2eDxKTEy0cSIAAIDw\nZetaGzk5OSosLNT48eMlSbt379b06dOv+fscOnSou0cD0MsNHjyY9xYAYcfWcMvKylJJSYmWL18u\nqTPkLkXc1frkNXIAAAA9mcOyLMvuIQAAAPDZety2BOxzCuBG2rt3r44cOaKnnnrK7lEA9AA1NTVa\nt26d4uPjNWbMGOXm5n7q5/e4nRMu7XP66KOP6p133rF7HAA9SFtbm5xOp5KSkuweBUAP4fF49MAD\nD+jrX/+6Pvjgg8/8/B4XbuxzCuBGiY6O1owZM+weA0APkp6ertTUVJ05cybQL5+mx4UbAACASWpr\na7V582YtWLDgMz/XiENS7HMK4Ea5lvcXALga1/K+0tTUpPXr1+uhhx5SVFTUZ35vI8KNfU4B3CjX\n8v5yrcsVAeidruV95VLIvfXWW3K73Z951M2IcGOfUwA3yrW+v0jSkiVLQjskAKNcy/vKww8/fE3f\n29hr3NjnFMCNwvsLgO7WXe8rxoYb+5wCuFF4fwHQ3brrfcXYcMvJydHu3bsDj3fv3q1JkybZOBGA\nnoL3FwDdrbveV4y4xq0r3bHPKQB0hfcXAN2tu95X2KsUAADAEMaeKgUAAOhtCDcAAABDEG4AAACG\nINwAAAAMQbgBAAAYgnADAAAwBOEGAABgCMINAADAEIQbgF7j1Vdf1XvvvWfLz964caP27t1ry88G\n0HMQbgB6rPfee08nT54MPHY4HPYNAwDdgHAD0GMdP348KNwAwHTGbjIPoPepqqrSyy+/rJycHJ04\ncUIej0czZ87UPffcc9nnrlq1SkePHpXL5VJRUZEee+wxSVJpaam2bNmi1tZWORwOPfnkk+rXr5/O\nnTunV155RcOHD9fp06d1//33Kzk5WevXr1dra6skacyYMbrvvvskSceOHdNvfvMb+f1+NTc3a968\necrLy5Mk1dfXa926dTp//rw6Ojo0cOBAJSQkBGbbt2+ftm/fLklKSEjQE088EfQ6AFyRBQCGqKqq\nsv7mb/7GOnDggGVZltXW1mY9+eST1oULF7r8/F/96lfW3r17A49/9rOfWStWrLC8Xq9lWZa1bds2\na9WqVYHv/bWvfc06fPiwZVmW1dLSYr3wwgtWbW1t4Ot/+ctfWjt27LAsy7JqamqslpYWy7Isq729\n3Xr66actr9dr+f1+a/ny5db+/fsDX1dSUmItXbo0MMsjjzwS+NrDhw9bTU1Nn/8PB0CvwBE3AEZJ\nTU3V1KlTJUkul0sjR47UuXPnlJqa2uXnW5YV+NjhcGj+/PlyOjvf+saPH6933nkn8Hrfvn01ceJE\nSdL777+vDz/8UD/5yU8Cr7e3t2vEiBGSpMjISP3rv/6rKisrZVmW6uvrVVdXp8bGRvl8Pk2bNi3w\ndZmZmZo1a1bg8cSJE/XDH/5QkyZN0s0336y4uLjP+acCoLcg3AAYJTY2NuhxVFRUUJxdy9c7nc6g\nr3W5XIGPHQ6HbrrpJn3nO9/p8vv84Ac/0P33368lS5ZIkp577rnA13XFsqzAz3riiSdUWVmpY8eO\n6eWXX9bChQs1adKkq/53ANB7cXMCgB4rKioqcH3atcrKytKZM2d0+PBhSZLf79cvf/lLlZeXS5Lq\n6uo0atQoSdLp06d1+vRpSdLw4cPlcrm0f//+wPcqLS3V3r175XA41N7erh07digtLU3z5s1Tbm6u\nKioqPs+/JoBehCNuAIxyLUt63HrrrfrRj36kP//5z4EjY1f7vaOjo/Xss89qzZo12rJli7xer7Kz\ns5Weni5JevDBB7VixQq53W4NHjxYN998cyASv/Wtb2nt2rUqLCyU3+/XwIEDNXv2bEmdR/UuXLig\nZcuWKT4+XvHx8YEbJwDgszisaznHAAAAANtwqhQAAMAQhBsAAIAhCDcAAABDEG4AAACGINwAAAAM\nQbgBAAAYgnADAAAwBOEGAABgiP8PN7XBlv+F9OsAAAAASUVORK5CYII=\n",
"text": [
"<matplotlib.figure.Figure at 0x108ba6dd0>"
]
}
],
"prompt_number": 11
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"And, logically enough, we peak around 50 threads, because anything between 50 and 99 threads\n",
"there is at least one thread that processes two requests.\n",
"All the other threads end up waiting."
]
}
],
"metadata": {}
}
]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment