2013年4月14日日曜日

rand vs. mt_rand; php編

先ほどFacebookでポストした内容、一応少しだけ補足を加えてブログにも。
これはphpのrandとmt_randの単純な繰り返し実行に速度的な有意差が認められるかを確認するコードのつもり。

なんでそんなものを書いたかと言うと、
この記事で
「randよりmt_randの方が速いからmt_randを使った方が良い」
と言っているのでなにゆーとんねん(そもそも速度の問題ではないのだが)という訳で。

補足として事のヒントを幾つか以下、リストに。
確かにPHP Manualのmt_rand()の解説にも
「平均的な libc の rand()よりも 4 倍以上高速に乱数を生成」
とか書かれてしまっているのだけど、それは事の本質ではないし、実際php-5.4でベンチマークしても有意差という程の事は無い。

ではmt_rand()が用意された事の本質とは何かと言えば、もちろん古い擬似乱数生成アルゴリズムかつphpの依存するC処理系の実装依存の線形合同法による低品質な擬似乱数の生成と処理系依存の回避と思われます。(推量なのは私はphp開発者でも無ければMLやリポジトリーを監視しているphpファンでも無いので。)

ところで、PHPマニュアルに書かれていた速度については何故有意差が先のベンチマークで生じていないのか。私はPHPを深く良くと言える程は知らないので一般論としての推量に留まりますが、少しだけこれも考えてみます。先ず、そもそも擬似乱数生成測度がアプリケーション全体としてのボトルネックになりえる程の状況はごく一部の膨大な数の擬似乱数を必要とするシミュレーションなど特別な例に限られる程度の事です。その上で、PHPインタープリターの裏でC実装のネイティブコードの関数が走るにせよ、そもそものPHPレベルでの変数と値の取り扱い、関数呼び出し、構文解析が低速なので実際問題randとmt_randの速度面での有意差は生じなかったのではないかと思います。

或いはひょっとしたらこの元のドキュメント(英語版)にも4倍速いって書いてあるので、それを書いた人がメルセンヌツイスター乱数について諸情報を斜め読みしているうちにSFMTがMTに比べて凡そ4倍以上高速というデータを誤って拾ってしまったか…。少なくともMTは一般的な線形合同法の実装に対して4倍も高速ではないはず。さらにアルゴリズムについて語っているので、仮にSFMTを比較にするならば他のアルゴリズムもSIMD最適化して比較しないと比較にならない。巷には「XORSHIFTよりSFMTの方が速いよ!」とか言ってる人もいるけど、私が昔実装したSIMD最適化したXORSHIFTは当然SFMTより高速に大量の擬似乱数を生成したもんですけどねぇ…。

なお、メモリー消費の点で考えればMTは線形合同法より乱数生成器の状態保持に遥かに大きなメモリーを必要とします。とは言え、これは同時に大量のインスタンスをサーバー上で…とか考えなくても良い範疇では問題になる事も無いでしょう。(そもそも、サーバーのハードウェアリソースも考慮するとか速度が欲しいとか言うのにphpとか意味が分からないのでC++erを雇いましょう。)

0 件のコメント:

コメントを投稿