gracetory’s blog

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

PHP3番勝負!第1回 チキチキこの処理どっちが速いのか選手権〜!!

f:id:ykira:20180404183953p:plain

暖かくを通り越して暑くなってきましたが、皆様いかがお過ごしでしょうか。プログラマのykiraと申します。

今年は花粉症の症状が悪化して過ごし辛い毎日を送っております。だいぶ落ち着いてはきましたが、、、

さて、最近ReLIFEというマンガ(アニメ)にドハマりしています!

日代さんがイチオシなのですが、大神くんも狩生さんもその他の子らも、みんないい子でみんなカワイイです!!

なんと、著者が大分県出身で登場人物の名字が大分にある駅名だったりで、大分出身の私には楽しすぎるマンガとなっております。

しかも、私の母方の旧姓が太神(おおが)(大じゃなくて太ですが)だったり、弟の子どもが新太(あらた)だったりで、勝手に親近感。

面白いんで、みなさんも良かったら読んでみてくださいー

本題

、、、さて本題に入ります。

PHPに限らず、プログラム言語には同じような動作をするメソッドが複数あったりします。

これどっちが速いのかな?とネットで調べますが、大抵の場合は書かれていることを鵜呑みにしてそのまま使っていることが多いです。

今回は私が気になっている3つの処理に絞って、実際に測ってみたいと思います。

実行環境

サーバはGPCのクラウドです。

CPU : 1vCPU
メモリ : 約3.8G
OS : CentOS 6.9
PHP : 7.0.21

テスト用のサーバなので、本番スペックで計測すると結果が変わるかもですね。

実行方法

使用したプログラムはコチラー。

github.com

↓こんな感じで5回測り、処理毎に60秒のウェイトを取りながら計測します。

for i in {1..5};do /usr/local/php7/bin/php test1-1.php;sleep 60;done

5回分の結果から、一番良い結果と一番悪い結果を省いた3回分の平均で比べてみます。

平均は小数第5桁目を四捨五入しますー

1番勝負 echoとprintってどっちが速いの?

さて、さっそく計測結果を見ていきましょう。

100万回ループしてecho or printにて出力しています。

// echoの場合
$ for i in {1..5};do /usr/local/php7/bin/php test1-1.php;sleep 60;done
1回目 : 0.284 秒
2回目 : 0.280 秒
3回目 : 0.274 秒
4回目 : 0.276 秒
5回目 : 0.273 秒
平均 : 0.2767 秒

// printの場合
$ for i in {1..5};do /usr/local/php7/bin/php test1-2.php;sleep 60;done
1回目 : 0.285 秒
2回目 : 0.271 秒
3回目 : 0.277 秒
4回目 : 0.288 秒
5回目 : 0.282 秒
平均 : 0.2813 秒

正直、どちらも変わらないという印象です。

100万回以上出力する場合なら変わってくるかもですが、プロジェクトで統一されていれば問題ないかと思います。

2番勝負 in_arrayとarray_key_existsってどっちが速いの?

昔やったことあるような気がしますが、改めて検証します。

100万件の配列から、1万回ずつin_array or array_key_existsしています。

// in_arrayの場合
$ for i in {1..5};do /usr/local/php7/bin/php test2-1.php;sleep 60;done
1回目 : 15.874 秒
2回目 : 18.890 秒
3回目 : 19.815 秒
4回目 : 18.206 秒
5回目 : 17.885 秒
平均 : 18.327 秒

// array_key_existsの場合
$ for i in {1..5};do /usr/local/php7/bin/php test2-2.php;sleep 60;done
1回目 : 0.002 秒
2回目 : 0.002 秒
3回目 : 0.002 秒
4回目 : 0.002 秒
5回目 : 0.001 秒
平均 : 0.002 秒

圧倒的じゃないか、array_key_existsは。

実行した瞬間「え!?」ってなりました。

積極的にarray_key_existsを使っていきましょう!

3番勝負 forとwhileってどっちが速いの?

これC言語とかでも最初は戸惑いますよね〜。

forの方がわかりやすいので、そっち使うことが多い気がします。

それぞれ1億回ループを回しています。

// forの場合
$ for i in {1..5};do /usr/local/php7/bin/php test3-1.php;sleep 60;done
1回目 : 1.030 秒
2回目 : 0.899 秒
3回目 : 0.941 秒
4回目 : 0.944 秒
5回目 : 0.881 秒
平均 : 0.928 秒

// whileの場合
$ for i in {1..5};do /usr/local/php7/bin/php test3-2.php;sleep 60;done
1回目 : 0.885 秒
2回目 : 0.893 秒
3回目 : 1.021 秒
4回目 : 1.187 秒
5回目 : 0.954 秒
平均 : 0.956 秒

whileの方が速いと書いている記事を見かけましたが、どっちもどっちかなーという印象です。

これも開発メンバーがわかりやすい方でいいんじゃないでしょうか。

おまけ インクリメント(デクリメント)の++(--)、 後ろに書くか? 前に書くか?

おまけでこれも検証してみます。ちなみに私は後ろに書く派です。

インクリメント(デクリメント)をそれぞれ1億回ループで回しています。

// 後ろに書いた場合
$ for i in {1..5};do /usr/local/php7/bin/php test4-1.php;sleep 60;done
1回目 : 1.577 秒
2回目 : 1.971 秒
3回目 : 1.563 秒
4回目 : 2.843 秒
5回目 : 1.517 秒
平均 : 1.703 秒

// 前に書いた場合 
$ for i in {1..5};do /usr/local/php7/bin/php test4-2.php;sleep 60;done
1回目 : 1.598 秒
2回目 : 1.583 秒
3回目 : 1.505 秒
4回目 : 1.477 秒
5回目 : 1.518 秒
平均 : 1.5353 秒

前に書いた方が速いのかなぁという印象です。

これも正直どっちでも良いような気がしますが、プロジェクトとして統一できるのであれば前に書いたほうが良さそうです。

まとめ

「推測するな。計測せよ。」ということで計測してみました。

あくまで「弊社のテストサーバでは」という結果となりますので、自分の環境でも試してみてください。

富豪的プログラミングという言葉が聞かれて久しいですが、こういう細かいところの知識ももっておくといいかもしれません。

とりあえず、ReLIFEオススメです。