なぜ今更比較するのか
- Juliaを知って3年経つけど他の言語と比較とかを自分でしてこなかったから
- 初学者でも簡単に速さについて驚いてもらいたいから
- Pythonを使っていたプログラムをJuliaにしただけで早くなった感動を共有したかったから
おおまかにはこのへんで他にも理由はありますが、長くなるので割愛します。
誰に向けてか
- Juliaについて知らない、触ったことない人
- Pythonに限界を感じている人
- プログラミングをやったことなくても簡単に速いプログラムが書きたい人
私自身プログラミング経験豊富であったり、JuliaやPythonについてなんでも知っているようなベテランではありません。
なのでこの記事はJuliaについて詳しい人や、Pythonをマスターして意のままに操れる人には何言ってんだもっと色々あるだろと思われる内容です。
逆に理系大学生は研究のプログラムがいまいちだと感じたら読んでみるといいかもしれません。
なぜPythonなのか
- Juliaと比較されることが一番多い言語だと個人的に思った
- Juliaは汎用的言語だからPythonと比較したかった
- 機械学習をJuliaで取って代わりたい
当然インタプリタのPythonとコンパイラのJuliaは工夫をしなきゃJuliaが勝つに決まってますが、これは初学者向けなので難しい工夫とかをしなくても高速にかけるよということを示したかったのでPythonと比較してます。
そのため、静的言語も今回選考対象外です。
実行環境
- Python 3.10.12
- Julia 1.11.1
- Ubuntu 22.04.5
比較するプログラムについて
今回処理する内容は、
- プログラムが簡単
- 処理時間も増やしやすい
- 真値があって結果の比較もできる
この3点から交代級数をプログラムしたいと思います。
交代級数とは
交代級数とは分母の数が$1/2, 1/3, 1/4...$と増ふやしてそれを足し引きする数学の定番公式です。
式は以下のようにかけます
$$
S = \sum_{i=1}^{N} \frac{(-1)^{i-1}}{i}
$$
この級数の和は、$N$ を無限大にしたときに自然対数の2に収束します
$$
\lim_{N \to \infty} S_N = \ln(2)
$$
交代級数を使えば$N$を増やせば簡単に処理速度を重くでき、真値との比較もしやすいです。
PythonとJuliaの実行速度の比較
実際の処理をしていきます。
環境はJuliaとPythonなのでやっぱりJupyterを使いたいと思います。
Pythonのコード
import time
import math
sum = 0;
N = 10000000;
start = time.perf_counter(); #計測開始
for i in range(1, N+1):
sum += 1 / i * (-1) ** (i - 1);
stop = time.perf_counter(); #計測終了
print("交代和 :", sum);
print("真値 :", math.log(2));
print("実行時間[s] :", stop-start);
実行結果
交代和 : 0.6931471305601064
真値 : 0.6931471805599453
実行時間[s] : 2.1115614400005143
Juliaのコード
sum = 0.0
N = 10000000
# @elapsedはスコープ内の処理時間の計算を行える
elapsed_time = @elapsed begin
for i = 1:N
sum += 1 / i * (-1)^(i - 1)
end
end
println("交代和 : ", sum)
println("真値 : ", log(2))
println("実行時間[s] : ", elapsed_time)
実行結果
交代和 : 0.6931471305601064
真値 : 0.6931471805599453
実行時間[s] : 1.386452364
比較結果
時間
Pythonは2.1秒、Juliaは約1.4秒
0.7秒速いですがあんまりと思われる方もいるかもしれません
計算結果
有効桁数は7桁で、値はまさかの全く一緒、言語によって差が出るものもしばしばあるのですがすごい
その他
強いて言うならJuliaはlogや計測にライブラリを使わないのでちょっと楽
ただし、こんなので終わるJuliaではない!
先程難しい工夫はしないと言いましたが、簡単な工夫で高速にできるならしてみたいですよね。
なんとJuliaは関数にいれるだけで速くなります。
Juliaのコード(関数)
# juliaの関数名はスネークケース推奨
function alternating_series()
sum = 0.0
N = 10000000
for i = 1:N
sum += 1 / i * (-1)^(i - 1)
end
return sum
end
# @elapsedで処理時間を変数に格納
elapsed_time = @elapsed sum = alternating_series()
# 結果を表示
println("交代和 : ", sum)
println("真値 : ", log(2))
println("処理時間[s] : ", elapsed_time)
実行結果
交代和 : 0.6931471305601064
真値 : 0.6931471805599453
処理時間[s] : 0.395924064
計算結果は変わらず、まさかの1秒も巻いて約4分の1に!!
Pythonより1.7秒も速いです!
まとめ
- JuliaはPythonよりも圧倒的に速い
- ライブラリについても調べなくても数値計算に必要なものはデフォルトで入っている
- 精度などもPythonと一緒
Juliaは簡単でかつPythonより圧倒的に速いです。
インタプリタで1000万もループ回して2秒ちょいのPythonも十分ですがこの簡易的な内容での1.7秒はシステムが大きくなったり、複雑化してくると後々活きてくるので大切です。
こんなに簡単で速い言語のJulia是非みなさんもお試しあれ。