phpスクリプトの速度改善
はじめまして。CyberXのエンジニア青木といいます!
今回はphpスクリプトを見直して処理速度を改善しましょうというお話です。
普段書き慣れたコーディング手法が実はけっこう時間かかっているのでは?
と前々から疑問に思っていたところ、ブログ執筆が良いきっかけとなったので今回の調査に至りました。
まず、下記インクリメントの違いについて調べてみました。
・$a++(後置加算子)
・++$a(前置加算子)
・$a=$a+1
・$a+=1
計測用に下記のスクリプトを作り、インクリメントの部分だけ書き換えてそれぞれ10000万回ループさせてみました。
for($a=0;$a<10000;$a++)
{
// something do
}
結果は下記の通りで一番早かったのは「$a+=1」となりました。
反対に「++$a」は一番時間がかかってるようですね。
・$a++(0.616msec)
・++$a(0.806msec)
・$a=$a+1(0.729msec)
・$a+=1(0.519msec)
次に、下記ループの違いについても調べてみました。
・for
・while
・foreach
インクリメントの計測で下記スクリプトの結果は0.616msecとお伝えしました。
for($a=0;$a<10000;$a++)
{
// something do
}
whileも同様に下記のスクリプトを作って10000万回計測したところ、
while($a<10000)
{
// something do
$a++;
}
計測結果は0.689msecとなりました。
最後にforeachで計測したところ、
foreach($loop_ary as $value)
{
// something do
}
計測結果は0.671となりました。
これといって速度に違いは見られず、違いを期待していただけに残念でした。
そこで、評価式に関数を使った場合についても調べてみました。
これまでと同様に10000万回のループで評価式にphp組み込み関数のcount()を使ったケースです。
for($a=0;$a{
// something do
}
計測結果は2.166msecとなりました。
評価式に関数を使わない場合に比べると、約3.5倍程度の時間がかかっている事がわかりました。
またwhileで配列のキー、値を順次セットで取得する下記のケースも調べてみました。
while(list($key,$value)=each($loop_ary))
{
// something do
}
結果は3.953msecです。評価式に関数を2つ使ってる事もあり、
使わない場合に比べると、なんと5倍以上の時間がかかっている事がわかりました。
配列からキー、値を順次セットで取得する場合はforeachの下記構文でも
取得できますので、こちらも同様に計測してみたところ、
foreach($loop_ary as $key => $value)
{
// something do
}
すると、計測結果は0.868msecとなりました。
先ほどのwhileに比べると1/4以下の処理速度となりました。
ループの処理速度は何をを使っても大差はありませんでした。
しかし、評価式に関数を入れるとループの回数分だけ実行されるため余計なオーバーヘッドがかかります。
よって、変数に退避させて評価式に含めるといった対策を心がけるようにしましょう。
今回は基礎構文のみに限定した計測となりましたが、改善の余地はまだまだありそうです。
実行するマシンスペックよっても処理速度は変わってくると思いますが、皆様も見直されてみてはいかがでしょうか?