なぜNim
以前Rustの記事を投稿しましたが、情報を集めている段階で、第二プログラミング言語として Rust はオススメしません Nim をやるのですという記事を見つけました。
この記事の筆者はRustよりNim押しとのことのようです。
プログラミング言語として書きやすいというのはメリットですが、そのために遅くなるということであれば、やはりRustに軍配があがります。
実質どうなのかということを計測してみようという試みです。
動作環境
- raspberryPi 4B+ 4G
- Ubuntu 20.04 LTS (Focal Fossa)
はじめ方
※ちょっとこの辺いい加減
Nimの公式HPから作業を進めます。
公式では「Linux:おそらくすでにコンパイラがインストールされています。そうでない場合は、パッケージマネージャを使用してgccまたはをインストールしますclang」と出ています。
ソース
それはさておき、本論のプログラムです。
import random
import times
randomize()
const TEST_MAX = 10000000
const LOOP_MAX = 100
var x, y = 0.0
var ave = 0.0
for loop in 1..LOOP_MAX:
echo $loop & " times"
var time_start = cpuTime()
var count = 0
for test in 1..TEST_MAX:
x = rand(0.0..1.0)
y = rand(0.0..1.0)
# echo $x
# echo $y
if ( x * x + y * y <= 1):
count += 1
echo "pi:" & repr(float(4.0 * float(count) / float(TEST_MAX)))
var time_split = cpuTime() - time_start
echo "split" & repr(time_split)
ave += time_split
echo "AVE:" & repr(ave / float(LOOP_MAX))
実行します。
$ nim c -r montecarlo.nim
ubuntu@rubic:~/test/nim$ nim c -r montecarlo.nim
Hint: used config file '/etc/nim/nim.cfg' [Conf]
Hint: system [Processing]
Hint: widestrs [Processing]
Hint: io [Processing]
Hint: pi [Processing]
Hint: random [Processing]
Hint: algorithm [Processing]
Hint: times [Processing]
Hint: strutils [Processing]
Hint: parseutils [Processing]
Hint: math [Processing]
Hint: bitops [Processing]
Hint: macros [Processing]
Hint: unicode [Processing]
Hint: options [Processing]
Hint: typetraits [Processing]
Hint: posix [Processing]
Hint: [Link]
Hint: operation successful (33338 lines compiled; 2.061 sec total; 57.289MiB peakmem; Debug Build) [SuccessX]
Hint: /home/ubuntu/test/nim/montecarlo [Exec]
1 times
pi:3.141098
split7.109979792
2 times
pi:3.1426588
split7.118244570999999
3 times
pi:3.141072
split7.104846675999999
4 times
pi:3.14189
split7.107189147
5 times
pi:3.1422588
split7.111559454999998
あんまり早くないですね・・・・
ちなみにRustで同等の処理をしたところ、0.50 0.21秒程度の速度はキープされています。
そう思ったので、調べたところ、こちらにもリリースバージョンのコンパイルがありました。
ubuntu@rubic:~/test/nim$ nim c -r -d:release montecarlo.nim
Hint: used config file '/etc/nim/nim.cfg' [Conf]
Hint: system [Processing]
Hint: widestrs [Processing]
Hint: io [Processing]
Hint: pi [Processing]
Hint: random [Processing]
Hint: algorithm [Processing]
Hint: times [Processing]
Hint: strutils [Processing]
Hint: parseutils [Processing]
Hint: math [Processing]
Hint: bitops [Processing]
Hint: macros [Processing]
Hint: unicode [Processing]
Hint: options [Processing]
Hint: typetraits [Processing]
Hint: posix [Processing]
Hint: [Link]
Hint: operation successful (33338 lines compiled; 1.863 sec total; 57.281MiB peakmem; Release Build) [SuccessX]
Hint: /home/ubuntu/test/nim/montecarlo [Exec]
1 times
pi:3.1416876
split0.324142685
2 times
pi:3.1408588
split0.323515077
3 times
pi:3.1419296
split0.3237577979999999
4 times
pi:3.1421108
split0.323726781
5 times
pi:3.1412412
split0.323485295
0.3秒ですか・・・
結論として
この程度のプログラムであればNimに軍配が上がる。という結論になりました。
第二プログラミング言語として Rust はオススメしません Nim をやるのですに従い、Nimは魅力的な言語と言えそうです。
モンテカルロ法での円周率計算は複数言語で試しているのですが、現状最速 rustの乱数生成器をXoshoroにした版が最速という結論となっています。