[PHP] 関数実行の時に"namespace","class","function"それぞれの実行速度を調査

2018年12月25日

PHP テクノロジー プログラミング

PHPフレームワークを自作している時に、ちゃんとnamespace構成でメソッドを管理するようにしようと思って設計していた時の事。 class内の関数に、「public」を使ってアクセス制限をかけないようにして、「static」を用いて外部メモリ常駐するようにすると、関数が増えてきた時に、メモリが圧迫されてしまうのではないかと不安になります。 そもそも、オレオレフレームワークにおいて、namespaceでの管理をしなくても、functionのベンダープレフィックスとしての名称管理をするだけの方が効率がいいのではないか?と考えが浮かんできてしまった。 なんとなく、今時のシステムだからclassオブジェクト化、関数の名称被りを極力無くしたいがための、namespace構成にするのが一般的だという思い込みを捨ててみてはどうだろうと考えた時に、 これらの実行速度を計測して検討してみることにした。

計測ルール

phpの実行速度を計測したいので、ターミナルコマンドで"time"と"php-cli"を使って実行してその結果の値を比較してみたいと思います。 実行するプログラム内容は、echo ".";という1バイト分の文字列表示を10,000回行なって、それぞれ呼び出し環境を"namespace" , "class" , "function" , "normal"という階層構造の順に行なってみます。 ちなみに、実行速度はブレが発生するので、それぞれ3回行なってみます。 そして今回の実行環境は、「MacBook core-i7 1.4GHz メモリ16GB」にインストールしたDockerで行います。 Docker内部環境は、「Ubuntu 16.04.1 LTS , Nginx 1.10.0 PHP 7.0.22」です。

Placeコード

<?php for($i=0; $i<10000; $i++){ echo "."; } 実行結果 # 1回目結果 real 0m0.026s user 0m0.010s sys 0m0.010s # 2回目結果 real 0m0.390s user 0m0.130s sys 0m0.180s # 3回目結果 real 0m0.067s user 0m0.020s sys 0m0.030s まあまあ値がブレているのは、ミリ秒単位であることと、仮装サーバーだからかもしれませんね。 とりあえずは、最初に実行した最小値を参考にしてみようと思います。 やってみて気が付いたのですが、立て続けに実行すると、実行時間が増えていく事象を確認しました。 おそらくメモリ解放される前に次の実行をしてしまう事で、メモリ管理処理が追加されてしまっているようにも思えます。

functionコード

<?php for($i=0; $i<10000; $i++){ view(); } function view(){ echo "."; } 実行結果 # 1回目結果 real 0m0.106s user 0m0.010s sys 0m0.050s # 2回目結果 real 0m0.082s user 0m0.020s sys 0m0.030s # 3回目結果 real 0m0.120s user 0m0.030s sys 0m0.040s なんとなく負荷値が上がった感覚がありますね。 最低値を考えると0.082ぐらいですね。 何度かやってみましたが、0.06ぐらいが最低値っぽいですが、今回は計測値のみを使用します。

classコード

<?php for($i=0; $i<10000; $i++){ view_cs:: view(); } class view_cs{ function view(){ echo "."; } } 実行結果 # 1回目結果 real 0m0.089s user 0m0.040s sys 0m0.010s # 2回目結果 real 0m0.146s user 0m0.030s sys 0m0.040s # 3回目結果 real 0m0.113s user 0m0.050s sys 0m0.010s functionよりもほんの若干だけ増えている印象です。

namespaceコード

<?php namespace view_ns; for($i=0; $i<10000; $i++){ \view_ns\view_cs:: view(); } class view_cs{ function view(){ echo "."; } } 実行結果 # 1回目結果 real 0m0.119s user 0m0.040s sys 0m0.040s # 2回目結果 real 0m0.124s user 0m0.020s sys 0m0.050s # 3回目結果 real 0m0.109s user 0m0.000s sys 0m0.060s さらに増加している様子ですね。

まとめ

今回の計測結果での最低値を並べてみます。 normal.php : 0m0.026s function.php : 0m0.082s class.php : 0m0.089s namespace.php : 0m0.109s 想像通り、負荷値は上がっていますね。 より速度の早いシステムを求められる場合、こういう視点での考慮も必要という事です。 ただし、負荷の高かったnamespaceは、大きなシステム開発では、使った方がはるかに効率的で、不具合も少なくできる事が想定できるので、単純にスピードだけでの仕様決定はできないのが現実です。 そもそも、プログラム言語においても、階層構造化されている事を考えると、今回の計測結果は当たり前の事なんですが、一度仕様決定してしまうと、その後に構成を変える事はほぼ不可能になってしまうので、悩む際の資料の一つに使ってもらえると幸いです。

このブログを検索

ごあいさつ

このWebサイトは、独自思考で我が道を行くユゲタの少し尖った思考のTechブログです。 毎日興味がどんどん切り替わるので、テーマはマルチになっています。 もしかしたらアイデアに困っている人の助けになるかもしれません。