Created
July 30, 2017 05:55
-
-
Save genkuroki/a182e978752eba62caf88423558fd08a to your computer and use it in GitHub Desktop.
Python3/Julia_perf.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": "# JuliaとPythonの速度比較" | |
}, | |
{ | |
"metadata": {}, | |
"cell_type": "markdown", | |
"source": "## Fibonacci数の計算" | |
}, | |
{ | |
"metadata": { | |
"trusted": true, | |
"collapsed": true | |
}, | |
"cell_type": "code", | |
"source": "using BenchmarkTools", | |
"execution_count": 1, | |
"outputs": [] | |
}, | |
{ | |
"metadata": { | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "function fibseq(n)\n if n < 2\n return n\n end\n a, b = 1,0\n for i in 1:n-1\n a,b = a+b,a\n end\n return a\nend\nfibseq(20) == 6765", | |
"execution_count": 2, | |
"outputs": [ | |
{ | |
"output_type": "execute_result", | |
"execution_count": 2, | |
"data": { | |
"text/plain": "true" | |
}, | |
"metadata": {} | |
} | |
] | |
}, | |
{ | |
"metadata": { | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "@benchmark fibseq(20)", | |
"execution_count": 3, | |
"outputs": [ | |
{ | |
"output_type": "execute_result", | |
"execution_count": 3, | |
"data": { | |
"text/plain": "BenchmarkTools.Trial: \n memory estimate: 0 bytes\n allocs estimate: 0\n --------------\n minimum time: 11.196 ns (0.00% GC)\n median time: 11.197 ns (0.00% GC)\n mean time: 11.886 ns (0.00% GC)\n maximum time: 1.074 μs (0.00% GC)\n --------------\n samples: 10000\n evals/sample: 1000" | |
}, | |
"metadata": {} | |
} | |
] | |
}, | |
{ | |
"metadata": { | |
"trusted": true | |
}, | |
"cell_type": "code", | |
"source": "@benchmark fibseq(30)", | |
"execution_count": 4, | |
"outputs": [ | |
{ | |
"output_type": "execute_result", | |
"execution_count": 4, | |
"data": { | |
"text/plain": "BenchmarkTools.Trial: \n memory estimate: 0 bytes\n allocs estimate: 0\n --------------\n minimum time: 17.261 ns (0.00% GC)\n median time: 17.728 ns (0.00% GC)\n mean time: 18.083 ns (0.00% GC)\n maximum time: 51.785 ns (0.00% GC)\n --------------\n samples: 10000\n evals/sample: 1000" | |
}, | |
"metadata": {} | |
} | |
] | |
}, | |
{ | |
"metadata": {}, | |
"cell_type": "markdown", | |
"source": "**Pythonとの比較**\n\n`fib(20)` では\n\n Python: 70ns\n Julia: 11ns\n\n`fib(30)` では\n\n Python: 78ns\n Julia: 18ns\n\nJuliaの側が4倍以上速い。\n\nしかも、Pythonの側はJulia並の速度を出すためにCythonを使うなどの工夫が施されている。\n\nそれに対して、Julia側のコードは上を見ればわかるようにスピードアップのための工夫を一切していない。\n\nそれにも関わらず、Julia側がPythonよりも数倍速い。\n\n要するにたとえ Cython を使っても速度的に Julia 側の工夫されていないコードに勝てないようだ。\n\n**Python側での結果の引用**\n\n私のパソコンでは\n\nhttps://gist.github.com/jfpuget/b53f1e15a37aba5944ad\n\nを実行したところ、以下のような結果になった。\n\nIn[1]:\n```Python\n%load_ext Cython\n%load_ext line_profiler\n\nimport random\nimport numpy as np\nfrom numba import jit\nimport sys\n\nif sys.version_info < (3,):\n range = xrange\n```\n\nIn[11]:\n```Python\ndef fib_seq(n):\n if n < 2:\n return n\n a,b = 1,0\n for i in range(n-1):\n a,b = a+b,a\n return a\n```\n\nIn[12]:\n```Python\n@jit\ndef fib_seq_numba(n):\n if n < 2:\n return n\n a,b = 1,0\n for i in range(n-1):\n a,b = a+b,a\n return a \n```\n\nIn[13]:\n```Python\n%%cython\n\ndef fib_seq_cython(n):\n if n < 2:\n return n\n a,b = 1,0\n for i in range(n-1):\n a,b = a+b,a\n return a \n\ncpdef long fib_seq_cython_type(long n):\n if n < 2:\n return n\n cdef long a,b\n a,b = 1,0\n for i in range(n-1):\n a,b = a+b,a\n return a\n```\n\nIn[14]:\n```Python\n%timeit fib_cache(20)\n%timeit fib_seq(20)\n%timeit fib_seq_cython(20)\n%timeit fib_seq_cython_type(20)\n%timeit fib_seq_numba(20)\n```\n\nOut[15]:\n```\n119 ns ± 2.9 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)\n1.33 µs ± 7.13 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)\n714 ns ± 5.28 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)\n70.1 ns ± 1.2 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)\n214 ns ± 13.5 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)\n```\n\nIn[16]:\n```Python\n%timeit fib_cache(30)\n%timeit fib_seq(30)\n%timeit fib_seq_cython(30)\n%timeit fib_seq_cython_type(30)\n%timeit fib_seq_numba(30)\n```\n\nOut[16]:\n```\n119 ns ± 1.34 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)\n1.93 µs ± 68.8 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)\n993 ns ± 13 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)\n78.1 ns ± 0.637 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)\n210 ns ± 14.2 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)\n```\n\nPython側のコードについては\n\nhttps://www.ibm.com/developerworks/community/blogs/jfp/entry/Python_Meets_Julia_Micro_Performance?lang=en\n\nも参照せよ。" | |
}, | |
{ | |
"metadata": { | |
"trusted": true, | |
"collapsed": true | |
}, | |
"cell_type": "code", | |
"source": "", | |
"execution_count": null, | |
"outputs": [] | |
} | |
], | |
"metadata": { | |
"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" | |
}, | |
"toc": { | |
"threshold": 4, | |
"number_sections": true, | |
"toc_cell": false, | |
"toc_window_display": false, | |
"toc_section_display": "block", | |
"sideBar": true, | |
"navigate_menu": true, | |
"moveMenuLeft": true, | |
"widenNotebook": false, | |
"colors": { | |
"hover_highlight": "#DAA520", | |
"selected_highlight": "#FFD700", | |
"running_highlight": "#FF0000", | |
"wrapper_background": "#FFFFFF", | |
"sidebar_border": "#EEEEEE", | |
"navigate_text": "#333333", | |
"navigate_num": "#000000" | |
}, | |
"nav_menu": { | |
"width": "252px", | |
"height": "49px" | |
} | |
}, | |
"gist": { | |
"id": "f6ac524e9de3275984cefcd66572233c", | |
"data": { | |
"description": "Python3/Julia_perf.ipynb", | |
"public": true | |
} | |
}, | |
"_draft": { | |
"nbviewer_url": "https://gist.github.com/f6ac524e9de3275984cefcd66572233c" | |
} | |
}, | |
"nbformat": 4, | |
"nbformat_minor": 2 | |
} |
実際にコードと実験結果を私と同じようにJupyter notebookの形式でで見せてくれると助かります。実際のコードと実験結果を多くの人に見せる方が建設的だと思います。論よりコード。
もしかして、再帰呼び出し版のfib()の話をしたいのかな?こういう計算をするときには普通函数の再帰呼び出しはしないと思う。
なるほど、フィボナッチ数の20番目や30番目の計算は軽過ぎて、Cythonでコンパイルされた結果を走らせるときの律速段階が馬鹿にならないんですね。methaneさん、勉強になりました。どうもありがとうございます。
https://twitter.com/genkuroki/status/899325911593439232 でこの話を広報しておきました。
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Cython 側が遅いのは、計算中はC言語のlong型を使っているものの、入出力のときにPythonの多倍長整数型との変換が入るからだと思います。
fib(20)とfib(30)の時間「差」ではJuliaとCythonに大きな差はありません。