これ
だいぶ古くなって、PHP7の事情とか反映できていないのもあって、計測し直してみるかと… で、そのときたまたま GitHub - phpbench/phpbench: PHP Benchmarking framework を使ったら、これが思いのほかよかった。というわけで GitHub に上げました。
PhpBench はベンチマークフレームワークです。基本、PHPUnit のように、ベンチマーク用のクラスに各シナリオを表すメソッドを書けばOK、あとは CLI から vendor/bin/phpbench run ...
で引数にオプションいろいろ指定して実行。
ここがよかった 1
setUp()
的なメソッドをアノテーションで指定できます。事前条件の準備がベンチマーク結果に影響しないよう、逃がせるのがいいです。
<?php /** * @BeforeMethods({"init"}) */ class PhpReferenceBench01Nop { protected $bigArray; public function init() { $this->bigArray = range(1, 100000); }
他に、PHPUnit の @dataProvider
のような ParamProviders もありました。複数パターンやるとき使えるますね。
ここがよかった2
ウォームアップや反復回数の指定が充実していました。
コマンドラインで --rev=100 --iterations=10
とすれば、100回分の処理時間を10セットやった平均、みたいにお手軽にやれます。
が、それだと「これ、やってること浅いから多めにやって平均取りたいな」「これ単価が高いから他と同じ回数やるのはしんどい」といった知識が残らないので、メソッドのアノテーションでこうしています。
<?php class PhpReferenceBench01Nop { /** * @Warmup(10) * @Revs(100) * @Iterations(10) */ public function benchNoRef() { $result = PhpReference::nopNoRef($this->bigArray); unset($result); }
@Warmup(10)
= メモリ断片化やコードキャッシュの影響を受けないよう、10回素振りしてから計測に入る@Revs(100)
= 100回分の合計を1回として評価する@Iterations(10)
= 10セットやってその平均/最高/最悪を取る
以前のものは、100万件のデータで1回でした。今回はデータを10万件に下げ、その代わり、Revsに100や50を指定して結果を安定させました。ロジックに影響することなく、実行のされ方 を独立して調整できるのが嬉しいですね。
ここがよかった3
結果表示の調整が簡単。Dockerを使って7と5を同時にやりたかったので、自分はPHPのバージョンを表示し、逆に、誤差の出にくいベンチなので平均実行時間以外を隠しました。こんな感じ https://github.com/tanakahisateru/php-ref-bench/blob/master/phpbench.json#L4
ていうか… シーケンシャルな配列のPHP5と7の差、変更時のコピー速度で約9倍、メモリでざっと3倍です。無駄コピーもなくなってる。どうしよう…参照のほうが遅いでしょって言えない…