Created
August 1, 2020 16:18
-
-
Save DarioSucic/337f1257fa26c3877f5115f7c2440d9d to your computer and use it in GitHub Desktop.
https://www.reddit.com/r/learnpython/comments/i1cctb/i_need_help_in_optimisating_appending_to_numpy/
This file contains 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
{ | |
"cells": [ | |
{ | |
"cell_type": "code", | |
"execution_count": 1, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"import numpy as np\n", | |
"import numba as nb" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 2, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"def setup():\n", | |
" bin_data = np.random.randint(0, 2, 10**3, dtype=np.uint8)\n", | |
" sign_length = 1000\n", | |
" return bin_data, sign_length" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 3, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"# https://www.reddit.com/r/learnpython/comments/i1cctb/i_need_help_in_optimisating_appending_to_numpy/fzwghgf/\n", | |
"def func_b(bin_data, sign_length):\n", | |
" bin_data = bin_data.reshape(len(bin_data), 1)\n", | |
" sign_length = np.ones(sign_length, dtype=int).reshape(1, sign_length)\n", | |
" signal = (bin_data*sign_length).ravel()\n", | |
" return signal" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 4, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"@nb.njit\n", | |
"def fast_repeat(bin_data, sign_length):\n", | |
" n = len(bin_data)\n", | |
" out = np.empty(n * sign_length, dtype=np.uint8)\n", | |
" for i in range(n):\n", | |
" row = i*sign_length\n", | |
" out[row:row+sign_length] = bin_data[i]\n", | |
" return out" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"##### Establish cost of generating data (used for calculating bandwidth)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 5, | |
"metadata": { | |
"scrolled": true | |
}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"8.59 µs ± 14.1 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)\n" | |
] | |
} | |
], | |
"source": [ | |
"%%timeit\n", | |
"bin_data, sign_length = setup()" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"##### Original (~1.45 MB/s)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 6, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"684 ms ± 31.6 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)\n" | |
] | |
} | |
], | |
"source": [ | |
"%%timeit\n", | |
"bin_data, sign_length = setup()\n", | |
"\n", | |
"signal = np.array([])\n", | |
"for bit in bin_data:\n", | |
" temp = np.full(sign_length,int(bit))\n", | |
" signal = np.append(signal,temp)" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"##### np.repeat (~400 MB/s)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 7, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"2.63 ms ± 61.3 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)\n" | |
] | |
} | |
], | |
"source": [ | |
"%%timeit\n", | |
"bin_data, sign_length = setup()\n", | |
"signal = bin_data.repeat(sign_length)" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"##### numpy broadcast (~625 MB/s)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 8, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"1.61 ms ± 8.64 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)\n" | |
] | |
} | |
], | |
"source": [ | |
"%%timeit\n", | |
"bin_data, sign_length = setup()\n", | |
"func_b(bin_data, sign_length) # primitive_screwhead" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"##### Numba compiled (~60 GB/s)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 9, | |
"metadata": { | |
"scrolled": true | |
}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"25.1 µs ± 77.7 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)\n" | |
] | |
} | |
], | |
"source": [ | |
"%%timeit\n", | |
"bin_data, sign_length = setup()\n", | |
"fast_repeat(bin_data, sign_length) # numba" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"#### Confirm that the output is correct" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 10, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"(True, True, True)" | |
] | |
}, | |
"execution_count": 10, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"bin_data, sign_length = setup()\n", | |
"a = bin_data.repeat(sign_length)\n", | |
"b = func_b(bin_data, sign_length)\n", | |
"c = fast_repeat(bin_data, sign_length)\n", | |
"\n", | |
"(a == b).all(), (a == c).all(), (b == c).all()" | |
] | |
} | |
], | |
"metadata": { | |
"kernelspec": { | |
"display_name": "Python 3.8.0 64-bit", | |
"language": "python", | |
"name": "python38064bitce923c4d35cd4821adec5b4dd96a59a2" | |
}, | |
"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.8.3" | |
} | |
}, | |
"nbformat": 4, | |
"nbformat_minor": 2 | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment