Last active
July 8, 2017 02:41
-
-
Save genkuroki/97d623818a1ce0df0fd42dc8b74e8466 to your computer and use it in GitHub Desktop.
Julia/SpeedUp.ipynb
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": [ | |
{ | |
"metadata": {}, | |
"cell_type": "markdown", | |
"source": "# スピードアップ!\n\nスピードアップのためには\n\n- Juliaの最適化を有効に活用するためには、速度が重要なコードはトップレベルでは函数の中に書く\n\n- if文による分岐ではなく、ifelse()函数を使う。\n\n- 型を合わせる。" | |
}, | |
{ | |
"metadata": {}, | |
"cell_type": "markdown", | |
"source": "## 例1\n\n以下のコードは\n\nhttp://bicycle1885.hatenablog.com/entry/2015/01/04/175916\n\nより" | |
}, | |
{ | |
"metadata": { | |
"trusted": false | |
}, | |
"cell_type": "code", | |
"source": "versioninfo()", | |
"execution_count": 28, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": "Julia Version 0.6.0\nCommit 903644385b* (2017-06-19 13:05 UTC)\nPlatform Info:\n OS: Windows (x86_64-w64-mingw32)\n CPU: Intel(R) Core(TM) i7-4770HQ CPU @ 2.20GHz\n WORD_SIZE: 64\n BLAS: libopenblas (USE64BITINT DYNAMIC_ARCH NO_AFFINITY Haswell)\n LAPACK: libopenblas64_\n LIBM: libopenlibm\n LLVM: libLLVM-3.9.1 (ORCJIT, haswell)\n" | |
} | |
] | |
}, | |
{ | |
"metadata": { | |
"ExecuteTime": { | |
"end_time": "2017-07-05T04:02:35.587000+09:00", | |
"start_time": "2017-07-04T19:02:31.271Z" | |
}, | |
"trusted": false | |
}, | |
"cell_type": "code", | |
"source": "tic()\ncircle_in = 0.0\nfor i in 1:100000000\n l = (rand()^2 + rand()^2) ^ 0.5\n if l <= 1\n circle_in = circle_in + 1\n end\nend\nprintln(4 * circle_in / 100000000)\ntoc()", | |
"execution_count": 29, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": "3.1414384\nelapsed time: 3.321732766 seconds\n" | |
}, | |
{ | |
"data": { | |
"text/plain": "3.321732766" | |
}, | |
"execution_count": 29, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
] | |
}, | |
{ | |
"metadata": { | |
"ExecuteTime": { | |
"end_time": "2017-07-05T04:00:28.517000+09:00", | |
"start_time": "2017-07-04T19:00:27.424Z" | |
}, | |
"trusted": false | |
}, | |
"cell_type": "code", | |
"source": "# 函数化\n#\n# Juliaの最適化はトップレベルのコードではゆるい。\n# 函数化するとしっかり最適化してくれる。\n# 函数化するだけで2~3倍速くなる。\n\nfunction calc_pi()\n circle_in = 0.0\n for i in 1:100000000\n l = (rand()^2 + rand()^2) ^ 0.5\n if l <= 1\n circle_in = circle_in + 1\n end\n end\n println(4 * circle_in / 100000000)\nend\n\n@time calc_pi()", | |
"execution_count": 30, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": "3.14163052\n 1.074469 seconds (3.34 k allocations: 170.293 KiB)\n" | |
} | |
] | |
}, | |
{ | |
"metadata": { | |
"ExecuteTime": { | |
"end_time": "2017-07-05T04:00:35.141000+09:00", | |
"start_time": "2017-07-04T19:00:32.415Z" | |
}, | |
"trusted": false | |
}, | |
"cell_type": "code", | |
"source": "# 0.5乗→sqrt()\n#\n# 0.5乗よりsqrt()函数の方が少し速い。\n\nfunction calc_pi()\n circle_in = 0.0\n for i in 1:100000000\n l = sqrt(rand()^2 + rand()^2)\n if l <= 1\n circle_in = circle_in + 1\n end\n end\n println(4 * circle_in / 100000000)\nend\n\n@time calc_pi()", | |
"execution_count": 31, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": "3.14165848\n 1.021270 seconds (3.15 k allocations: 161.693 KiB)\n" | |
} | |
] | |
}, | |
{ | |
"metadata": { | |
"ExecuteTime": { | |
"end_time": "2017-07-05T04:00:41.667000+09:00", | |
"start_time": "2017-07-04T19:00:38.872Z" | |
}, | |
"trusted": false | |
}, | |
"cell_type": "code", | |
"source": "# 型合わせ 整数 1 → 浮動小数点 1.\n\nfunction calc_pi()\n circle_in = 0.0\n for i in 1:100000000\n l = sqrt(rand()^2 + rand()^2)\n if l <= 1.\n circle_in = circle_in + 1.\n end\n end\n println(4 * circle_in / 100000000)\nend\n\n@time calc_pi()", | |
"execution_count": 39, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": "3.14179612\n 1.009002 seconds (2.94 k allocations: 152.984 KiB)\n" | |
} | |
] | |
}, | |
{ | |
"metadata": { | |
"ExecuteTime": { | |
"end_time": "2017-07-05T04:00:46.625000+09:00", | |
"start_time": "2017-07-04T19:00:44.863Z" | |
}, | |
"trusted": false | |
}, | |
"cell_type": "code", | |
"source": "# 分岐排除 if → ifelse()\n#\n# 分岐を函数化すると速くなる。\n\nfunction calc_pi()\n circle_in = 0.0\n for i in 1:100000000\n l = sqrt(rand()^2 + rand()^2)\n circle_in += ifelse(l <= 1., 1., 0.)\n end\n println(4 * circle_in / 100000000)\nend\n\n@time calc_pi()", | |
"execution_count": 44, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": "3.14144624\n 0.625683 seconds (2.99 k allocations: 154.954 KiB)\n" | |
} | |
] | |
}, | |
{ | |
"metadata": { | |
"ExecuteTime": { | |
"end_time": "2017-07-05T04:00:53.218000+09:00", | |
"start_time": "2017-07-04T19:00:52.288Z" | |
}, | |
"trusted": false | |
}, | |
"cell_type": "code", | |
"source": "# sqrt()の排除\n#\n# 数学的には平方根はいらない。\n\nfunction calc_pi()\n circle_in = 0.0\n for i in 1:100000000\n l = rand()^2 + rand()^2\n circle_in += ifelse(l <= 1., 1., 0.)\n end\n println(4 * circle_in / 100000000)\nend\n\n@time calc_pi()", | |
"execution_count": 46, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": "3.14163048\n 0.427451 seconds (2.90 k allocations: 150.105 KiB)\n" | |
} | |
] | |
}, | |
{ | |
"metadata": { | |
"ExecuteTime": { | |
"end_time": "2017-07-05T04:00:58.339000+09:00", | |
"start_time": "2017-07-04T19:00:57.392Z" | |
}, | |
"trusted": false | |
}, | |
"cell_type": "code", | |
"source": "# 2乗 → x*x\n#\n# これはあんまり速くならない感じ。\n\nfunction calc_pi()\n circle_in = 0.0\n for i in 1:100000000\n x, y = rand(), rand()\n l = x*x + y*y\n circle_in += ifelse(l <= 1., 1., 0.)\n end\n println(4 * circle_in / 100000000)\nend\n\n@time calc_pi()", | |
"execution_count": 50, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": "3.14142424\n 0.421646 seconds (2.91 k allocations: 148.668 KiB)\n" | |
} | |
] | |
}, | |
{ | |
"metadata": { | |
"collapsed": true | |
}, | |
"cell_type": "markdown", | |
"source": "## 例2\n\n以下の例は\n\nhttp://bicycle1885.hatenablog.com/entry/2016/12/13/205646\n\nより" | |
}, | |
{ | |
"metadata": { | |
"trusted": false, | |
"collapsed": true | |
}, | |
"cell_type": "code", | |
"source": "ks = rand(1:10,10^6);\nxs = rand(10^6);", | |
"execution_count": 88, | |
"outputs": [] | |
}, | |
{ | |
"metadata": { | |
"trusted": false | |
}, | |
"cell_type": "code", | |
"source": "tic()\n s = 0\n for x in ks\n s += x\n end\ntoc()\n\n@show s", | |
"execution_count": 123, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": "elapsed time: 0.145923908 seconds\ns = 5496147\n" | |
}, | |
{ | |
"data": { | |
"text/plain": "5496147" | |
}, | |
"execution_count": 123, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
] | |
}, | |
{ | |
"metadata": { | |
"trusted": false | |
}, | |
"cell_type": "code", | |
"source": "tic()\n s = 0\n for x in xs\n s += x\n end\ntoc()\n\n@show s", | |
"execution_count": 125, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": "elapsed time: 0.157144876 seconds\ns = 499609.5068853918\n" | |
}, | |
{ | |
"data": { | |
"text/plain": "499609.5068853918" | |
}, | |
"execution_count": 125, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
] | |
}, | |
{ | |
"metadata": { | |
"trusted": false | |
}, | |
"cell_type": "code", | |
"source": "# 函数化\n\nfunction sumup(xs)\n s = 0\n for x in xs\n s += x\n end\n return s\nend\n\n@show @time sumup(ks)\n@show @time sumup(xs);", | |
"execution_count": 116, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": " 0.009164 seconds (760 allocations: 41.048 KiB)\n@time(sumup(ks)) = 5496147\n 0.058194 seconds (3.00 M allocations: 45.827 MiB, 17.38% gc time)\n@time(sumup(xs)) = 499609.5068853918\n" | |
} | |
] | |
}, | |
{ | |
"metadata": { | |
"trusted": false | |
}, | |
"cell_type": "code", | |
"source": "# s と xs の中身の型を合わせる\n\nfunction sumup(xs)\n s = zero(eltype(xs))\n for x in xs\n s += x\n end\n return s\nend\n\n@show @time sumup(ks)\n@show @time sumup(xs);", | |
"execution_count": 117, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": " 0.009248 seconds (856 allocations: 46.360 KiB)\n@time(sumup(ks)) = 5496147\n 0.009475 seconds (859 allocations: 46.609 KiB)\n@time(sumup(xs)) = 499609.5068853918\n" | |
} | |
] | |
}, | |
{ | |
"metadata": { | |
"trusted": false | |
}, | |
"cell_type": "code", | |
"source": "@show eltype([0.0 1.;])\n@show eltype(0)\n@show eltype(\"abc\");", | |
"execution_count": 118, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": "eltype([0.0 1.0;]) = Float64\neltype(0) = Int64\neltype(\"abc\") = Char\n" | |
} | |
] | |
}, | |
{ | |
"metadata": { | |
"trusted": false | |
}, | |
"cell_type": "code", | |
"source": "# 実は既存のsum()函数を使った方がずっと速い\n\n@show @time sum(ks)\n@show @time sum(xs);", | |
"execution_count": 170, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": " 0.000756 seconds (5 allocations: 176 bytes)\n@time(sum(ks)) = 5496147\n 0.000697 seconds (5 allocations: 176 bytes)\n@time(sum(xs)) = 499609.5068853926\n" | |
} | |
] | |
}, | |
{ | |
"metadata": { | |
"collapsed": true, | |
"trusted": false | |
}, | |
"cell_type": "code", | |
"source": "", | |
"execution_count": null, | |
"outputs": [] | |
} | |
], | |
"metadata": { | |
"_draft": { | |
"nbviewer_url": "https://gist.github.com/97d623818a1ce0df0fd42dc8b74e8466" | |
}, | |
"gist": { | |
"id": "97d623818a1ce0df0fd42dc8b74e8466", | |
"data": { | |
"description": "Julia/Bench mark test.ipynb", | |
"public": true | |
} | |
}, | |
"kernelspec": { | |
"name": "julia-0.6", | |
"display_name": "Julia 0.6.0", | |
"language": "julia" | |
}, | |
"language_info": { | |
"file_extension": ".jl", | |
"name": "julia", | |
"mimetype": "application/julia", | |
"version": "0.6.0" | |
} | |
}, | |
"nbformat": 4, | |
"nbformat_minor": 2 | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment