Skip to content

Instantly share code, notes, and snippets.

@genkuroki
Last active July 8, 2017 02:41
Show Gist options
  • Save genkuroki/97d623818a1ce0df0fd42dc8b74e8466 to your computer and use it in GitHub Desktop.
Save genkuroki/97d623818a1ce0df0fd42dc8b74e8466 to your computer and use it in GitHub Desktop.
Julia/SpeedUp.ipynb
Display the source blob
Display the rendered blob
Raw
{
"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