Web制作・開発会社 プレスマンのスタッフブログ

PRESSMAN*Tech

phpの処理を高速に!

インクリメントとデクリメントは前置

//遅い
$i++;
$i--;

//早い
++$i;
--$i;

約1.24倍の高速化

型変換は関数よりキャストする

//遅い
$tmp = intval($val);

//早い
$tmp = (int)$val;

約2.1倍の高速化

数字(not数値)を計算で使うなら事前にキャストする

//遅い
$val = '1';
$tmp = 0;
$tmp += $val;

//早い
$val = '1';
$val = (int)$val;
$tmp = 0;
$tmp += $val;

約1.7倍の高速化

グローバル変数より定数を使う

//遅い
$GLOBALS[ 'MIZUKI' ] = 7;
$tmp = '';
$tmp = $GLOBALS[ 'MIZUKI' ];

//早い
define( 'hoge', 7 );
$tmp = '';
$tmp = hoge;

約1.7倍の高速化

forよりwhileを使う

//遅い
for( $i = 0; $i < 100000; ++$i){}

//早い
$i = 0;
while($i < 100000){
++$i;
}

約1.19倍の高速化

forの判定条件に関数等を使わない

//遅い
for($i = 0; $i < count( $array ); ++$i) { ... }

//早い
$count = count( $array );
for($i = 0; $i < $count; ++$i) { ... }

ループの外に出せる処理は外で行う

//遅い
for($i = 0; $i < 100000; ++$i){
$key = array_search(1, array(1,2,3,4,5,6,7) );
}
//早い
$array = array(1,2,3,4,5,6,7);
for($i = 0; $i < 100000; ++$i){ $key = array_search(1, $array ); } 

約2倍の高速化

比較演算子は、完全一致で判定する

//遅い 
if($val == 1){ ... } if($val != 1){ ... } 
//早い 
if($val === 1){ ... } if($val !== 1){ ... } 

ほぼ変わらないが高速化

Bool値を条件判定は、比較演算子を使わない

//遅い
if($bool === true){ ... }

//早い
if($bool){ ... }

約1.2倍の高速化

三項演算子よりif文を使う

//遅い
$hoge = true ? 1 : 0;

//早い
if( true ){
    $hoge = 1;
}else{
    $hoge = 0;
}

ほぼ変わらないが高速化

if文は頻度の高い分岐側をelseにする

//遅い
if( true ){

}
else{

}

//早い
if( false ){

}
else{

}

ほぼ変わらないが高速化

switch文は頻度の高い条件を先に書く

//遅い
$val = 1;
switch( $val ){
    case 7: break;
    case 6: break;
    case 5: break;
    case 4: break;
    case 3: break;
    case 2: break;
    case 1: break;
    default:
}
//早い
$val = 1;$tmp1 = $tmp2 = 1;
switch( $val ){
    case 1: break;
    case 2: break;
    case 3: break;
    case 4: break;
    case 5: break;
    case 6: break;
    case 7: break;
    default:
}

約2.7倍の高速化

文字列連結は「.(ドット)」で

$str = "hoge";
//遅い
$tmp = "hoge $str";
//早い
$tmp = "hoge " . $str;

約1.27倍の高速化

文字列からの1文字抽出は配列として抽出する

$str = "hoge";
//遅い
$val = substr( $str, 4, 1 );
//早い
$val = $str[4];

約2.9倍の高速化

文字列の置換はstr_replace()の方がpreg_replace()より速い

$str = "hoge";
//遅い
preg_replace('/hoge/', 'piyo', $str);
//早い
str_replace('hoge', 'piyo', $str);

約2.1倍の高速化

文字列を分解する時は、preg_split()よりexplode()

$str = "h,o,g,e";
//遅い
$array = preg_split('/,/', $str);
//早い
$array = explode(',',$str);

文字列が含まれているかはpreg_match()よりstrpos()

$val = "hogehoge";
//遅い
if( preg_match( '/hoge/' , $val ) ){}
//早い
if( strpos( $val, 'hoge' ) !== false ){}

約2.4倍の高速化

同じ値の複数変数への代入は分けて行う

//遅い
$tmp1 = $tmp2 = 1;
//早い
$tmp1 = 1;
$tmp2 = 1;

約1.4倍の高速化

変数がbool型か調べる時は比較演算子を使う

//遅い
if( is_bool( $v ) ){}
//早い
if( $v === true || $v === false ){}

約1.8倍

配列に要素を追加する時は、[]で代入

//遅い
array_push($array, 'hoge');
//早い
$array[] = 'hoge';

約1.2倍の高速化

出力はprint()ではなくechoを使う

//遅い
print '';
//早い
echo '';

約1.1倍の高速化

echoで複数文字列を出力する時は「.」ではなく「,」で繋ぐ

//遅い
echo '' . '';
//早い
echo '' , '';

約1.4倍の高速化

現在時刻を取得時は$_SERVER['REQUEST_TIME']を使う

//遅い
$now = time();
//早い
$now = $_SERVER['REQUEST_TIME'];

ほぼ変わらないが高速化

ダブルクォーテーションよりシングルクォーテーション

//遅い
$str = "hoge";
//早い
$str = 'hoge';

ほぼ変わらないが高速化

in_array()よりisset()

$array[hoge]='hoge';
//遅い
if(in_array(500, $array)){...}
//早い
if(isset($array[hoge])){...}

※一度、配列のkeyにユニークな値を設定してisset()で探索
約30倍の高速化

fgetcsvよりSplFileObjectを使う

//遅い
if (($handle = fopen($filepath, "r")) !== false) {
    while (($line = fgetcsv($handle, 1000, ",")) !== false) {
        $records[] = $line; 
    } 
    fclose($handle); 
}
//早い
$file = new SplFileObject($filepath); 
$file->setFlags(SplFileObject::READ_CSV); 
foreach ($file as $line) {
    $records[] = $line; 
}

約2倍の高速化

さいごに

前回は、フロントエンドの高速化について、
書かせていただいたので、
今回の記事はバックエンド(php)の記事に致しました!

可読性を考慮することも大事なので、
必ずしも紹介した書き方がいいというわけでもないと思います。

参考にしたサイト

PHPを少しでも速く動かしたい
PHPのarray_pushとin_arrayの速度について
【PHP】その CSV 変換、本当に「fgetcsv」でいいの?