Skip to content

Instantly share code, notes, and snippets.

@genkuroki
Created July 30, 2017 05:55
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 genkuroki/a182e978752eba62caf88423558fd08a to your computer and use it in GitHub Desktop.
Save genkuroki/a182e978752eba62caf88423558fd08a to your computer and use it in GitHub Desktop.
Python3/Julia_perf.ipynb
Display the source blob
Display the rendered blob
Raw
{
"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
}
@methane
Copy link

methane commented Aug 20, 2017

Cython 側が遅いのは、計算中はC言語のlong型を使っているものの、入出力のときにPythonの多倍長整数型との変換が入るからだと思います。
fib(20)とfib(30)の時間「差」ではJuliaとCythonに大きな差はありません。

@genkuroki
Copy link
Author

実際にコードと実験結果を私と同じようにJupyter notebookの形式でで見せてくれると助かります。実際のコードと実験結果を多くの人に見せる方が建設的だと思います。論よりコード。

@genkuroki
Copy link
Author

もしかして、再帰呼び出し版のfib()の話をしたいのかな?こういう計算をするときには普通函数の再帰呼び出しはしないと思う。

@genkuroki
Copy link
Author

なるほど、フィボナッチ数の20番目や30番目の計算は軽過ぎて、Cythonでコンパイルされた結果を走らせるときの律速段階が馬鹿にならないんですね。methaneさん、勉強になりました。どうもありがとうございます。

@genkuroki
Copy link
Author

https://twitter.com/genkuroki/status/899325911593439232 でこの話を広報しておきました。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment