Sak 関数ベンチを Squeak/Pharo Smalltalk で

絶対どっかにありそうだけど、ベンチマーク用関数 fib_m() を考えてみた。

  • fib_m(0 or 1) = 1
  • fib_m(n) = fib_m(n-1) * fib_m(n-2)

Sak 関数と呼んで下さい。

Diary - 2016 July 研究日記


これを Squeak/Pharo Smalltalk で試してみました。

"メソッド版"
Integer compile: 'fibM
    ^self caseOf: {[0]->[1]. [1]->[1]}
        otherwise: [(self-1) fibM * (self-2) fibM]'.

[40 fibM] timeToRun

"Squeak5.0 [msec] => 1987 "
"Pharo5.0 => 0:00:00:02.096 " 
"ブロック版"
| fibM |
fibM := nil.
fibM := [:n |
    n caseOf: {[0]->[1]. [1]->[1]}
        otherwise: [(fibM value: n-1) * (fibM value: n-2)]
].

[fibM value: 40] timeToRun

"Squeak5.0 [msec] => 3025 "
"Pharo5.0 => 0:00:00:02.986 "


Node.js(V8)にこそ僅差で負けていますが、Squeak/Pharo Smalltalk の Cog VM もなかなかの速度をたたき出しています。

$ gcc -o sak_bench sak_bench.c


$ time ./sak_bench
real    0m0.913s
user    0m0.890s
sys     0m0.000s
$ cat sak_bench.js
function fib_m(n){
    if(n == 0) return 1;
    if(n == 1) return 1;
    return fib_m(n-1)*fib_m(n-2);
}

fib_m(40);


$ node -v
v0.10.31


$ time node sak_bench.js
real    0m1.681s
user    0m0.000s
sys     0m0.000s

Ruby の最近のビルドは試していなかったので、ほとんどその存在を忘れかけていた rbenv で 2.4.0-dev をインストールして手元の環境で試してみたところこんな感じになりました。

$ ruby -v
ruby 2.4.0dev (2016-07-03 trunk 55566) [x86_64-cygwin]


$ time ruby sak_bench.rb
real    0m16.726s
user    0m16.133s
sys     0m0.424s


ささださんのところの環境よりちょっとだけ速い結果を出すようですが、言語によって前後するようです。

$ gosh -V
Gauche scheme shell, version 0.9.5_pre1 [utf-8,pthreads], x86_64-unknown-cygwin


$ time gosh sak_bench.scm
real    0m13.953s
user    0m13.905s
sys     0m0.000s
$ python3 -V
Python 3.4.3


$ time python3 sak_bench.py
real    0m50.436s
user    0m50.390s
sys     0m0.015s
$ python2 -V
Python 2.7.10


$ time python2 sak_bench.py
real    0m42.712s
user    0m42.390s
sys     0m0.109s


ついでに Ruby でも Proc 版も試してみます。

$ cat sak_bench_proc.rb
fib_m = ->(n){
  case n
  when 0, 1
    1
  else
    fib_m[n-1] * fib_m[n-2]
  end
}

fib_m[40]


$ time ruby sak_bench_proc.rb
real    0m49.341s
user    0m48.775s
sys     0m0.302s