gracetory’s blog

東池袋にある合同会社グレストリのエンジニアブログです

推測するな。計測せよ。

f:id:grnishi:20180317212205j:plain

はじめに

プログラマのgrnishiです。好きな難読言語はBrainFuckです。

さてグレストリではサーバサイド言語にPHPが採用されていますが、特に深い意味があるわけではなく、ずっと使っているという事とPHP書けるプログラマが多いっていうのが理由でしょうか。

題名

題名に書いた「推測するな 計測せよ」とはプログラマなら誰でも当然知っているであろう格言です。

この格言の元となっているのは、Rob Pike氏のNotes on Programming in C (1989/2/21)に書かれている下記節が由来と言われています。

ルール1: プログラムがどこで時間を消費することになるか知ることはできない。ボトルネックは驚くべき箇所で起こるものである。したがって、どこがボトルネックなのかをはっきりさせるまでは、推測を行ったり、スピードハックをしてはならない。

ルール2: 計測すべし。計測するまでは速度のための調整をしてはならない。コードの一部が残りを圧倒しないのであれば、なおさらである。

ルール3: 凝ったアルゴリズムは nが小さいときには遅く、nはしばしば小さい。凝ったアルゴリズムは大きな定数を持っている。 nが頻繁に大きくなることがわかっていないなら、凝ってはいけない(nが大きくなるときでさえ、ルール2が最初に適用される)。

ルール4: 凝ったアルゴリズムはシンプルなそれよりバグを含みやすく、実装するのも難しい。シンプルなアルゴリズムとシンプルなデータ構造を使うべし。

ルール5: データはすべてを決定づける。もし、正しいデータ構造を選び、ものごとをうまく構成すれば、アルゴリズムはほとんどいつも自明のものになるだろう。プログラミングの中心は、アルゴリズムではなくデータ構造にある。

ルール6: ルール6は存在しない。

wikipedia - UNIX哲学

ある程度の経験を積んだプログラマなら、これまでの知識や経験に基いて感覚的にプログラムの良し悪しを判断してしまいがちです。

そんな時はこのルールを思い出し、計測をする事を忘れないようにしています。

と常々思っている所に以前下記のリポジトリを見つけたのを思い出しました。

github.com

様々なPHPフレームワークでHelloWorldを出力するだけのプログラムを書いてその実行速度やメモリ使用量などを計測する。ただそれだけのものです。

面白そうだったのでちょっとやってみました。

環境

GCP Compute Engine n1-standard-1 (vCPU×1、メモリ3.75GB)

CentOS 6.9

apache httpd 2.2.15

php 7.0.28

セットアップ

とりあえずなにはともあれgit

yum install -y git

phalconをコンパイルするのにgccとre2c

yum install gcc re2c 

httpdのインストール

yum install httpd

phpおよび関連モジュールのインストール

yum install --enablerepo=remi,remi-php70 php php-devel php-opcache php-mcrypt php-intlphp-curl php-mbstring php-pdo php-xml 

composerのインストール

curl -sS https://getcomposer.org/installer | php
mv composer.phar /usr/bin/composer

php-framework-benchmarkをダウンロード、セットアップ

cd /var/www/html/
git clone https://github.com/kenjis/php-framework-benchmark.git
cd php-framework-benchmark
bash setup.sh

なお、ここでsetup.shの後ろにフレームワーク名を指定すれば、そのフレームワークだけセットアップされます

bash setup.sh cake-3.2

とか。

ここで、phalconが動作しなかったのでphalconのインストールを

cd /usr/local/src/
git clone git://github.com/phalcon/cphalcon.git
cd cphalcon/build/
./install

apacheを再起動したら

/etc/init.d/httpd restart

準備完了です。

結果

実行は

/bin/sh benchmark.sh

で、一括で全フレームワーク計測してくれます。

framework requests per second relative peak memory relative
siler-0.6 2,876.36 10.8 0.35 1.0
staticphp-0.9 2,061.03 7.7 0.35 1.0
kumbia-1.0-dev 1,941.65 7.3 0.37 1.1
tipsy-0.10 1,823.54 6.8 0.36 1.0
phalcon-2.0 1,759.05 6.6 0.38 1.1
fatfree-3.5 1,448.01 5.4 0.43 1.2
ci-3.1 1,157.83 4.3 0.38 1.1
slim-3.0 1,109.92 4.2 0.55 1.6
nofuss-1.2 1,037.57 3.9 0.40 1.2
lumen-5.1 980.06 3.7 0.63 1.8
yii-2.0 922.85 3.5 0.91 2.6
ze-1.0 873.12 3.3 0.56 1.6
silex-2.0 828.10 3.1 0.66 1.9
bear-1.0 795.83 3.0 0.56 1.6
cygnite-1.3 747.43 2.8 0.58 1.7
phpixie-3.2 702.09 2.6 0.82 2.4
fuel-1.8 610.29 2.3 0.52 1.5
aura-2.0 514.24 1.9 0.70 2.0
cake-3.2 476.47 1.8 1.10 3.2
zf-3.0 389.26 1.5 1.10 3.2
symfony-3.0 351.85 1.3 1.40 4.0
laravel-5.3 267.31 1.0 2.04 5.9
http://127.0.0.1/php-framework-banchmark/

にアクセスするとグラフ表示も見れます。

f:id:grnishi:20180317123544p:plain

拙作FWも計測してみる

拙作FWに「Regalia」というものがあります。これ自体どこにも公開していないですし、時間と共に名前も中身もどんどん変わっていますので安定版というものも存在しません。

Regalia自体の紹介はまた別の機会にまわします。

痒い所に手が届くわけではなく、フルスタックで様々な機能が提供されているわけではありません。
厳しいルールを押し付けず、かつ失敗しやすい部分を未然に防ぐ事を目的にしています。

というものを思想としています。要は他FWより軽いけど、他FWほど利便性はありませんという事を目的としています。

せっかくなのでこの拙作FWも計測してみます。

あと、ついでなのでピュアPHPでHelloWorld!だけ出力するものも作ってみました。

このベンチマークに新たなFWを追加するのは簡単で、

cd /var/www/html/php-framework-benchmark
mkdir FW名

と、FW用のディレクトリを作り、その中にソースコードを展開します。

必要であればsetup.shを_benchmarkディレクトリの中に作ってもいいです。

もう一つのルールとしては、Hello World!と出力した直後に

require $_SERVER['DOCUMENT_ROOT'].'/php-framework-benchmark/libs/output_data.php';

これをコピペしてもらえれば。メモリの使用量などを出力してくれます。

次にベンチマークスクリプトが叩くshを用意します。

cd FW名/_benchmark/
vi hello_world.sh

他のFWの同一ファイルを参考に書いて下さい。ただエンドポイントを書いておくだけです。

次にベンチマークを実行するリストに追加します。

vi /var/www/html/php-framework-bechmark/list.sh

つらつらと計測するFWが書かれているのでここに追加する。以上。

結果2

framework requests per second relative peak memory relative
plain-1.0 4,199.06 16.5 0.34 1.0
siler-0.6 2,881.79 11.3 0.35 1.0
staticphp-0.9 2,121.11 8.4 0.35 1.0
kumbia-1.0-dev 2,035.08 8.0 0.37 1.1
phalcon-2.0 1,858.46 7.3 0.38 1.1
tipsy-0.10 1,690.14 6.7 0.36 1.1
Regalia-5.0 1,462.77 5.8 0.47 1.4
fatfree-3.5 1,362.88 5.4 0.43 1.3
ci-3.1 1,169.97 4.6 0.38 1.1
slim-3.0 1,107.71 4.4 0.55 1.6
nofuss-1.2 1,079.31 4.2 0.40 1.2
lumen-5.1 1,018.73 4.0 0.63 1.9
yii-2.0 944.66 3.7 0.91 2.7
ze-1.0 857.21 3.4 0.56 1.7
silex-2.0 805.90 3.2 0.66 1.9
bear-1.0 731.90 2.9 0.56 1.7
phpixie-3.2 723.10 2.8 0.82 2.4
cygnite-1.3 716.84 2.8 0.58 1.7
fuel-1.8 660.59 2.6 0.52 1.5
aura-2.0 510.12 2.0 0.70 2.1
cake-3.2 445.88 1.8 1.10 3.2
symfony-3.0 378.97 1.5 1.40 4.1
zf-3.0 375.52 1.5 1.10 3.2
laravel-5.3 253.97 1.0 2.04 6.0

f:id:grnishi:20180317143905p:plain

拙作FWもなかなか良い位置にいますね。このあたりを狙って作っているので想定通りです。

ややInclude Fileが多いのは恐らく設定ファイル関係かなと。DBの設定、ログの設定、一般的な設定などと分けて用意していますので。

考察

今回はHello World!のみを出力する各種FWのベンチマークを計測しました。

これは特定のFWを持ち上げたり貶めたりするものではありません。実環境でHello World!だけ出力するなんて事はありませんからね。

DBへのアクセスや外部APIの呼び出し、セッション処理や何か計算など今回数字の良かったFWを採用したからといってこの辺りでも優位である保証はありませんし、

逆に下位の至れり尽くせりの方が楽な場合もあります。

適材適所でFWは選べば良いと思います。

さいごに

知らないFWもたくさんあったし、簡単なDBアクセスだけ書いてベンチマーク取ってみようかな。