PHPでは、コマンドを実行するための関数(sytem関数やexec関数)が用意されていますが、このような関数を使ってコマンドをうまく利用すると、プログラムの実行スピードを大幅に上げられる場合があります。
forやforeachによる繰り返し処理は、PHPが比較的苦手とする処理(時間がかかる処理)の一つです。
数が少ないうちはいいですが何万という繰り返しが入ってくると、処理はかなり重くなります。
以下は、ログファイルを分析するプログラム例で、10時台のアクセス数を調べています。
一つ目の方は全部PHPで、二つ目の方はコマンドを利用しています。環境はLinux系OSです。
<?php
//全ての処理をPHPで行う
$start_time = getTime();
$file = file('access_log');
$counter = 0;
foreach ($file as $data) {
//10:xx:xxという文字列があるかどうか
if (preg_match('/10:[0-5][0-9]:[0-5][0-9]/', $data)) {
$counter++;
}
}
$end_time = getTime();
var_dump($counter);
var_dump($end_time - $start_time);
//より正確なタイムスタンプを入手するための関数。
function getTime() {
$arr = explode(' ', microtime());
return $arr[1] + $arr[0];
}
?>
<?php
//コマンドを利用するプログラム
$start_time = getTime();
$cmd = 'grep 10:[0-5][0-9]:[0-5][0-9] access_log | wc -l';
exec($cmd, $status, $result);
$end_time = getTime();
var_dump($result);
var_dump($end_time - $start_time);
function getTime() {
$arr = explode(' ', microtime());
return $arr[1] + $arr[0];
}
?>
今回の例で使用したコマンドですが、
- grep (パターン) (ファイル名):正規表現で検索し、マッチした行を出力する。
- wc (ファイル名やデータ) :単語数を出力する。「-l」オプションをつけた場合は行数を出力する。
というものです。
また、「|」でコマンドをつなぐと、直前のコマンドの出力結果を次のコマンドの引数に渡します。
プログラムの実行結果ですが、ログファイルが1行だと、
- コマンド不使用:0.00096607208251953秒
- コマンド使用 :0.023474931716919秒
となり、繰り返し処理が無ければコマンドを使わない方が速くなりますが、
15000行のログファイルだと、
- コマンド不使用:0.20867109298706秒
- コマンド使用 :0.10673499107361秒
と、倍近くの差が出ました。
さらに倍の30000行だと
- コマンド不使用:0.41866302490234秒
- コマンド使用 :0.17369604110718秒
となり、繰り返し処理が増えるほど差が大きくなることがわかります。
ちなみに、今回ご紹介したコマンドはLinux系OSのもので、通常Windowsでは使えません。
あくまでPHPのプログラムなので、コマンドを使い過ぎるのはどうかと思いますが、UNIXコマンドには強力なものがたくさんあるので、状況に合わせてうまく使っていきましょう。
この記事は、アシアルが運営するPHP開発者のためのポータル&コミュニティサイト「PHPプロ!」で毎週配信しているPHP・TIPSメーリングリストを再録したものです。
同サイトでは、他にもPHP最新ニュースや、困ったときのQ&A掲示板、初心者向けのPHP講座など、PHP開発者をサポートする情報を掲載しています。