Skip to content

Instantly share code, notes, and snippets.

@kfsone
Created April 17, 2021 23:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kfsone/26101a25339aaf0d3a1ed2b159eb1b21 to your computer and use it in GitHub Desktop.
Save kfsone/26101a25339aaf0d3a1ed2b159eb1b21 to your computer and use it in GitHub Desktop.
Optimizations in Python
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The original hubris-constructed version."
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"def to_str(s: str) -> str:\n",
" return str(\"%s\" % str(s))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The first 'fix' by the last-person-to-touch-it."
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
"def just_str(s: str) -> str:\n",
" return str(s) # protect against someone passing a non-string in future."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"When it was asserted \"it's always a string\"..."
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [],
"source": [
"def its_a_str(s: str) -> str:\n",
" return s"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Benchmark tests"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [],
"source": [
"def f1(s: str) -> bool:\n",
" s = to_str(s)\n",
" if \"OK\" in s: return True\n",
" return False \n",
"\n",
"def f2(s: str) -> bool:\n",
" if \"OK\" in just_str(s): return True\n",
" return False\n",
"\n",
"def f3(s: str) -> bool:\n",
" if \"OK\" in its_a_str(s): return True\n",
" \n",
"def f4(s: str) -> bool:\n",
" return \"OK\" in s"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"319 ns ± 18.6 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)\n",
"205 ns ± 13.8 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)\n",
"140 ns ± 9.88 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)\n",
"and f4\n",
"93.9 ns ± 8.62 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)\n"
]
}
],
"source": [
"# Pathological cases\n",
"%timeit f1(\"feature set 32 is BROKEN\")\n",
"%timeit f2(\"feature set 32 is BROKEN\")\n",
"%timeit f3(\"feature set 32 is BROKEN\")\n",
"print(\"and f4\")\n",
"%timeit f4(\"feature set 32 is BROKEN\")"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"43.2 ns ± 5.82 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)\n"
]
}
],
"source": [
"# But, you know, it's only ever used in one place, so: what if...\n",
"%timeit \"OK\" in \"feature set 32 is BROKEN\""
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Lets look under the hood."
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
" 2 0 LOAD_GLOBAL 0 (str)\n",
" 2 LOAD_CONST 1 ('%s')\n",
" 4 LOAD_GLOBAL 0 (str)\n",
" 6 LOAD_FAST 0 (s)\n",
" 8 CALL_FUNCTION 1\n",
" 10 BINARY_MODULO\n",
" 12 CALL_FUNCTION 1\n",
" 14 RETURN_VALUE\n",
"---\n",
" 2 0 LOAD_GLOBAL 0 (to_str)\n",
" 2 LOAD_FAST 0 (s)\n",
" 4 CALL_FUNCTION 1\n",
" 6 STORE_FAST 0 (s)\n",
"\n",
" 3 8 LOAD_CONST 1 ('OK')\n",
" 10 LOAD_FAST 0 (s)\n",
" 12 CONTAINS_OP 0\n",
" 14 POP_JUMP_IF_FALSE 20\n",
" 16 LOAD_CONST 2 (True)\n",
" 18 RETURN_VALUE\n",
"\n",
" 4 >> 20 LOAD_CONST 3 (False)\n",
" 22 RETURN_VALUE\n"
]
}
],
"source": [
"import dis # part of python's standard library\n",
"dis.dis(to_str)\n",
"print(\"---\")\n",
"dis.dis(f1)"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
" 2 0 LOAD_GLOBAL 0 (str)\n",
" 2 LOAD_FAST 0 (s)\n",
" 4 CALL_FUNCTION 1\n",
" 6 RETURN_VALUE\n",
"---\n",
" 7 0 LOAD_CONST 1 ('OK')\n",
" 2 LOAD_GLOBAL 0 (just_str)\n",
" 4 LOAD_FAST 0 (s)\n",
" 6 CALL_FUNCTION 1\n",
" 8 CONTAINS_OP 0\n",
" 10 POP_JUMP_IF_FALSE 16\n",
" 12 LOAD_CONST 2 (True)\n",
" 14 RETURN_VALUE\n",
"\n",
" 8 >> 16 LOAD_CONST 3 (False)\n",
" 18 RETURN_VALUE\n"
]
}
],
"source": [
"dis.dis(just_str)\n",
"print(\"---\")\n",
"dis.dis(f2)"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
" 2 0 LOAD_FAST 0 (s)\n",
" 2 RETURN_VALUE\n",
"---\n",
" 11 0 LOAD_CONST 1 ('OK')\n",
" 2 LOAD_GLOBAL 0 (its_a_str)\n",
" 4 LOAD_FAST 0 (s)\n",
" 6 CALL_FUNCTION 1\n",
" 8 CONTAINS_OP 0\n",
" 10 POP_JUMP_IF_FALSE 16\n",
" 12 LOAD_CONST 2 (True)\n",
" 14 RETURN_VALUE\n",
" >> 16 LOAD_CONST 0 (None)\n",
" 18 RETURN_VALUE\n"
]
}
],
"source": [
"dis.dis(its_a_str)\n",
"print(\"---\")\n",
"dis.dis(f3)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The last function, `f4` makes no function call"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
" 14 0 LOAD_CONST 1 ('OK')\n",
" 2 LOAD_FAST 0 (s)\n",
" 4 CONTAINS_OP 0\n",
" 6 RETURN_VALUE\n"
]
}
],
"source": [
"dis.dis(f4)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"*However* it is worth noting the delta `f3(s)`->`f4(s)` and `f4(s)`->`\"OK\" in s` is ~40ns, and the commonality between the two is primarily the elision of a function call."
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.9.2"
}
},
"nbformat": 4,
"nbformat_minor": 4
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment