sci

最果て風呂

各種言語でベンチマーキングその2

やることがなくて暇じゃない?

辞書の要素数が 4400 に増えてきて変換への負荷が高まってきた。前回のベンチからずいぶんと経ったので、再度計測してみることにした。

方法について

  1. ブログ記事をローカルで保存している 3.4MB のテキストを変換対象とする。
  2. 歴史的仮名使いを新仮名使いに変換させる処理にかかった時間を計測する(timeコマンドとストップウオッチ)。
  3. 今回は時間がかかるので、各言語で 1 回ずつの実行とする。なお、Lisp 系は今回やらない。
  4. メモリの使用量もチェックする。

結果について

実行時間(s) メモリ使用量(MB) 備考
C#(mono) 10.929 9.0 お!
Gauche 438.547 8.7 CPU を 140% まで利用してる
Go(binary) 27.034 27.0 え〜?
Lua 206.096 14.1 ん…
Objective-C 306.352 2458.0 2.5GBも使ってやがる!
Cocoa Obj-C 340.000 206.0 応答なしになるが最後まで動作
Perl5 7.875 13.0 うむ
Python3 4.373 13.6 ほぇ〜!
Ruby 22.007 85.0 ぐぬっ
Emacs 7.900 - ふむ
Vim 488.025 - をいをい

f:id:nakinor:20150826064202p:plain

考察というか感想

前回の 2.6MB のテキストを使った時のベンチマークと今回の結果は、対 Python3 比で下記のような速度比率となった。

前回 今回
Python3 1.0 1.0
Perl5 1.2 1.8
Ruby 2.5 5.0
C# 2.8 2.5
Go 4.0 6.2
ObjC 63.9 70.1
Emacs 1.2 1.8
Vim 22.9 111.6
Gauche - 100.3
Lua - 47.1

Python3

相変わらず速くて、メモリの使用量も少ないみたい。素人が何のアルゴリズムも考えずに思い付いた手続を書いていくだけで、ある程度の性能を出してくれるのだから優秀な言語なんだと思う。プロが使う場合は知らん。ただオフサイドルール方式なのが残念。書いていてめっちゃストレスになるんだわコレ。

Perl5

Python3 に続いて速い。小さなテキストを扱うような普段使いの場合であれば、速度差はまったく気にする必要がないと思う。実は Ruby, Python3 の後に勉強をしたので、$_とか @$@$ とか eq とかが辛い。いや本来はもっと別な記法があるのかもしれないけれど、3 年前に書いてから現在までに修正以外では触れてはいない。

Ruby

個人的には一番長く使っていて、「とりあえず何かしよう」という時に使ってしまう。Perl5 と同じように、普段使いであれば問題はないのだけれど、こうやってベンチマークを取ってしまうと(普段使いしているだけに)気になってしまう……。

今回はメモリの使用量も調べてみたのだけれど、他の言語と比べてもかなり使ってるよねぇ。読み込んだテキストを一本にして全要素を each する方針は Python3 でも同じなんだけどなぁ。もっと良い方法があるのだろうか?

ぐっすん。ま、気楽に使えるからな。な?

C#

ちょっと意外だった。前回の 2.6MB テキストを用いた時も 10 秒程度だったんだよね。Mono のバージョンが 4 になっているのが影響しているのかな?メモリの使用量が少ないのもいいね。ただ、これって中間生成物だから、もしかしたら別のプロセスが動いていたのかもしれなくて、それを見逃がしていたのかも。MS が協力してるみたいなのでもっと良くなりそうな予感。

Go

一番残念に思っているやつ。コンパイル型はそれなりの書き方があるとは思うのだけれど、期待が大きかった分だけ落胆も大きいのだった。良く調べないで書いたというのもあるけど、それは Python3 も同じだし。「ちょろっと調べてサクっと実装でウマー」とはいかないものなんだね。

構文は自分にとっては書きやすいので、本格的に使っていきたい言語なのだけれど、やはり眠気には勝てないのだった。

Objective-C

期待していなかったので「ま、こんなもんか」って感じ。だいたいオブジェクト指向って何なんだよ!ファイルを二つに分けさせやがって。もっと手軽に書かせろってんだい。しかもしかも!遅いくせにメモリ使用量がもの凄いんだわ。2.5GB ってあんた!あほ〜っ。ま、アホなのは自分なんだけどさ。

不思議なのは CUI で動かした場合と GUI のガワを着せた場合とではメモリの使用量が異なること。実装的には CUI の方を先に作って、最近になってから Xcode の使い方を勉強して、やっと Cocoa で実装ができたという流れ。内部の関数はコピペで流用したのでほぼ同じなんだよね。どうしてなんだろう?

Cocoa は起動しただけでは 60MB 程度を消費し、変換をはじめるとどんどんとメモリを消費していって最終的に(今回は) 206MB を使用した。変換が終わると 60MB 程度に戻る。ちなみに途中でアプリケーションが「応答しません」になるのだけれど、動作はし続けて結果を出して戻ってくる。CUI の方はアプリケーション全体が終了するまで不要になったオブジェクトを整理しないのかなぁ。

単純に考えると 3.4MB のストリングに対して 3513 回の置換を行なうので、その度に新しいオブジェクトに乗せ換えるとすれば 3.4 * 3513 で 11.6GB 必要になるんだよね?でもそうなっていないのは、やっぱり幾分開放しているのだろうか?

Swift が出てきてオワコンだけれど、Xcode を起動してはちょろちょろ使っていくわい。やっぱマカーだからさ。

Gauche

再帰再帰

今回の計測で唯一 CPU を 140% 使用したやつ。何でだろ?使用するメモリ量も少ないし、機械を有効に使ってる感じがする。遅いけど。

λらむだλ

これは他のものと違って「ファイルを開いて一行ずつ読み込んでは置換処理をして端末に出力」という動作をしている。当初は他のものもそういう動作だったのだけれど、「丸ごと一気にやっちゃった方が早くね?」ということで変更したのだが、Scheme (というか Gauche) ではどうやって実装すればいいのかわからんかったのでそのままなんだわ。

関数型?

つい先日ちょろっと目にしたけれど「一行ずつ読込む」動作のところで「パイプを使った方がうんぬん」という現象が起きているのかな?

ま、手続き型で実装してるんですけどね、わからんから。

Lua

これも Scheme のやつと同じように「一行読み込んでは……」という方式。組み込みとかしないのでもう書くことは無いと思う。だから遅くても気にならない。

構文が Vim script に似てるなぁって。いや本当は逆で、自分は Lua の方を先に知ったので Vim script の方が Lua に似てるなぁって印象だった。

Emacs

あらかじめファイルを開いておいてからの変換なのでちょいとズルをしている。でも他のものと違って font-lock で色付けをしているので、その分は遅くなっているんだわ。

旧字旧仮名を新字新仮名に置換する作業(逆もあり)。方式が方式なだけに変換の結果が 100% OK になるということはなくて、通常は「段落ごとに変換してはチェックして次の段落へ」という作業を続けることになる。だから本当は速度なんて気にならない。置き換わった単語が目立って確認しやすければそれでいいんだわ。

Vim

おいこら!前回よりも(対 Python3 比で) 5 倍も遅くなってるじゃないのよ!

こちらも HighLight で色付けしているので編集作業はしやすいし、前述のように通常は速度も気にならない。Vim はバッファを外部のプログラムに渡してその結果を受け取ることができるので、Python3 のスクリプトに渡して結果を受け取ればいいのだし、気にすることは無いのよ。

でもやっぱり気になるなぁ。めちゃくちゃ不本意!

僕は Vim script が書けない。

追記

sbcl の実行ファイルの作り方がわかったので作成して実験をしてみたら、861.046 秒だった。また、メモリ使用量は最大で 85.6MB、たまに 25.5MB 程度まで落ちてから再度上昇していくことを繰り返していた。

う〜む、Lisp 系はこんな実力じゃないはずなんだよね。やっぱり関数型プログラミングに目覚めなきゃダメなんだろうなぁ。

表はいいけど図を修正するのが面倒なのでこのままにしておく。Gnuplot は頻繁に触らないからすぐに忘れちゃうんだよね……。

下記の追記2の付録を作成するにあたり README.md を書いていたのだけれど、その途中で mruby でも動いていたことを思い出した。実行してみると 76.449秒、メモリ使用量はなんと最大で 1.65GB にも逹っした。

追記その2

koron さん(とは艦娘収集家である。TwitterGitHubスクリーンネームが異なるので、koron さんなのか kaoriya さんなのか、どちらでお呼びすればいいのかいつも迷ってしまう。空メンションしてしまうのに注意な。さらに実は mattn さんと同一人物であるとまことしやかに言われており、混乱の度合いが深まっている。たぶん「香り屋の KoRoN さん」が正解に近いと思われる)に「ソースも提示せんでなに各種言語 dis ってんねんワレ!自分は安全な場所に居て根拠のないデマを流布し、他者を煽動するような輩は恥知らずであり下衆である」って言われてしまった。ぐっすん(;_;)。なのでここに置きました。