PHP速度対決!差が出る5パターン

PHP

今回はPHPで何気なく書いているコードを速度計測し、高速化が図れるようなコードを考察していきます。
普段私達が当たり前のように書いてるコード、意外と無駄が多かったりします。

一番身近なところだと標準出力のecho,print関数。
出力する時はどちらを使っても問題ありません。
でも実は大きな速度差が出てくるんです

ということで今回は知ったらすぐ実践できる、
コードの高速化を検証を交えながら紹介します!

スポンサーリンク

計測方法

//計測回数
define('COUNT',10);
//試行回数
define('TEST_COUNT',100000);
//小数点桁数
define('DECIMAL_DIGITS',10);
//平均値
$average = 0.0;

for($i = 0; $i < COUNT; $i++) {
	$start = microtime(true);
	for($j = 0; $j < TEST_COUNT; $j++) {
		//計測対象
	}
	$end = microtime(true);
	$result = $end - $start;
	echo number_format($result,DECIMAL_DIGITS)."秒<br>";
	$average += $result;
}
//平均値の出力
$average = number_format($average/COUNT,DECIMAL_DIGITS);
echo 'avarage:'. $average.'秒<br>';
//前回の計測結果(自己満)
session_start();
echo 'before:'.$_SESSION['before'].'秒';
//前回の計測結果を更新
$_SESSION['before'] = $average;

はい、無駄に凝ったものを作りました。
概要としては10万回同じ処理を繰り返して1回分のタイムを計ります
そしてそれを10回繰り返し、最終的な平均値を算出します。

(簡単に計るのであればmicrotime関数を使った11~17行目で充分です。はい。)

実際に測ってみた

No.1 echo VS print

みんな大好き標準出力。果たしてどちらが速いのか!ファイッ
●echo関数

echo '';

avarage:0.0256559134秒

●print関数

print '';

avarage:0.0357182026秒

結果:echo関数の勝利
0.01秒差でechoの方が速かった。
そもそもprintは返り値があって、echoは返り値がない。
これが速度に関係しているのかもしれない。

No.2 ===演算子 VS ==演算子

PHP、javascript話者の一番の迷いどころ。
型の比較に厳しい===演算子、みんなに優しい==演算子。
どちらが速いのか!ファイッ
●===演算子

'1' === '1';

avarage:0.0387856722秒

●==演算子

'1' == '1';

avarage:0.0792219639秒

結果:===演算子の圧勝
なんと、倍近くの差が出ました。
==演算子は比較の際にキャストが発生するので、速度が落ちるそう。
型比較で地雷を踏むことも多いので===演算子を使いましょう!

No.3 foreach VS for+count

foreachがうまく使えないタイミング?でたまに使ってしまうfor+count
どちらが速いのか!ファイッ
●foreach

$arr = array('','','');
foreach($arr as $value) {
	$value;
}

avarage:0.0671128988秒

●for+count

$arr = array('','','');
for($k = 0; $k < count($arr); $k++) {
	$arr[$k];
}

avarage:0.2939522028秒

結果:foreachの圧勝
やはりcount関数をかませているのもあってか、forだと速度は落ちた。

No.4 foreach VS for+count 番外編

では次はハンデとして少し遅くなりそうなforeachのkeyを取得した場合と
for文のcount関数を初期化時にのみ使用した場合を戦わせてみましょう。ファイッ
●foreach $key=>$value

$arr = array('','','');
foreach($arr as $key => $value) {
	$value;
}

avarage:0.0817322254秒
参考
valueのみ:0.0671128988秒
やはりkeyを取得させると少し遅くなるようです。
keyが不要の場合はvalueのみで回しましょう。

●for+count

$arr = array('','','');
for($k = 0,$cn = count($arr); $k < $cn; $k++) {
	$arr[$k];
}

avarage:0.1781846523秒
参考
countを毎回実行:avarage:0.2939522028秒
初期化時のみcount関数を実行させる方が倍近く速いですね。
結果:foreachを使おう(適当)

No.5 if VS switch

値で処理を分岐させるのに使ったりするifとswitch。
これもなかなか迷いどころなので戦わせてみましょう。ファイッ
●if

if('1' == '2') {
} else if('2' == '2') {
}

avarage:0.1120637894秒
※PHPのswitch文は内部で==演算子を使ってるとのことなので
if文も==演算子で計測しました。

●switch

switch('2'){
	case '1':
	case '2':
}

avarage:0.1080152988秒

結論:switchの勝利
とは言っても、一つ一つの結果を見てると誤差の範囲…?

ということで今回は5パターンの検証をしてみました。
意外と遅くなる処理を書いていた人もいるかと思います。僕もそうです。
是非、これを参考にコードの最適化をしてみてください!

PHP
スポンサーリンク
この記事が気に入ったら
いいね!しよう
最新情報をお届けします。
この記事を書いた人

スパイスファクトリー株式会社 Webエンジニア。フロントエンドやWebサイトの高速化が得意です。インフラ・バックエンドも一通りやってます。
個人的なお仕事のご依頼や情報交換などはお問い合わせまたはTwitterにメンションをお願いします。

ShoheiTaiをフォローする
このエントリーが役に立ったらシェアをお願いします!
イケてないコード – Webエンジニアのブログ

コメント

  1. 匿名 より:

    普段javaばっかりでphp詳しくはないですが

    No.3 は
    $max = count($arr);
    for($k = 0; $k < $max; $k++) {

    じゃないとフェアじゃないかなぁと。。。

    • shouhei.tai より:

      ご指摘ありがとうございます!
      確かにcount関数の分フェアじゃないですよね。
      ただ、今回の記事ではforeachとforの厳密な速度を比較するというより、「このアンチパターンだとこれだけ遅いですよ」という意味合いがあるので、このままとさせてください。
      言葉足らずで申し訳ありません。
      近々count外出しの場合も計測して追記させていただきます!
      ありがとうございました。

タイトルとURLをコピーしました