PEAR::Cache_Lite_Function

以前も書いたPEARライブラリに登録されているキャッシュ処理のクラスに関数の呼び出し結果をそのままキャッシュできるものも含まれている事に気づいたので使ってみた。
メモリベースのキャッシュ機構がメジャーなのだろうけど、いま仕事で扱っている程度であればディスクキャッシュでも十分ということで。
とある箇所で、操作していると"つっかかる感"があって、その場所を調べていくとDBと連動してごにょごにょしているところであるので導入したが、結構効果があった。
メソッドの呼び出し方を変えるだけなので比較的楽に使えてみんなハッピー。


詳細はPEARのドキュメントを見てもらう事にしてメモがてら、サンプルを書いておく。*1

<?php
require_once('Cache/Lite/Function.php');

class CacheTest{

 var $_cacheopts;

 function CacheTest(){
  $this->_cacheopts = array(
   "lifeTime"               => 3600,// cacheの有効時間(秒)
   "hashedDirectoryLevel"   => 2,  // cache階層
   "debugCacheLiteFunction" => true,// デバッグ出力 (標準出力に "Hit" or "fail"表示)
  );
 }

 function test($param = 0){
  $cache  =& new Cache_Lite_Function($this->_cacheopts);
  
  // 自身のメソッド"process"を呼び出す。引数は$param
  $result = $cache->call(array(&$this, "process"), $param);  
  
  return $result;
 }

 /**
  * 比較的重い処理 (1度呼び出した結果を保管したい対象の処理)
  * @param $init 
  */
 function process($init){
  $resp = $init;

  for($i=0; $i<5000000; $i++){
   $resp++;
  }

  return $resp;
 }
}

$cachetest = new CacheTest();

// 開始時間メモ
$stime = explode(' ', microtime());
$stime = $stime[1] + $stime[0];

print "start = ".$stime."\n";

// 処理実行
$resp = $cachetest->test($argv[1]);

// 終了時間から実行時間算出
$etime = explode(' ', microtime());
$etime = $etime[1] + $etime[0];
$time   = round(($etime - $stime), 4);

printf("%f seconds\n", $time);
printf("CacheTest::test response = %s\n", $resp);

?>

な具合である。
ここでは例として、コマンドライン引数で渡した値を初期値としてそこから500万回インクリメントするという重い処理の結果をキャッシュさせている。
で、これを実行すると1回目はキャッシュが効かないので普通に実行される。

/Users/hideack/tmp% php -q test.php 10
start = 1238689332.75
Cache missed !
1.634000 seconds
CacheTest::test response = 5000010

次にもう一度同じことを実行してみる

/Users/hideack/tmp% php -q test.php 10
start = 1238689377.62
Cache hit !
0.001300 seconds
CacheTest::test response = 5000010

今度はキャッシュから引かれたので実行時間が大幅に短くなっている。
こんな具合。


あぁ、久しぶりに技術的なこと書いた。

*1:もっともサンプルを書いて一番役に立てているのは自分かもしれない...。良く忘れてここを見て振り返る。