CakePHPとsymfonyのメモリ使用量を比較してみた

CakePHPを使っているとメモリ不足で落ちる」というなんだか微妙な話が挙がっているようなので休み中に検証してみました。CakePHPの1.1と1.2、それにsymfonyを対象としてORマッパーに意図的に大量データを取得させた場合のメモリの使用量を計測してみると、まぁほぼ妥当といってよい結果を得ることが出来ました。

とりあえず先に結論を。

  • メモリの最大使用量がphp.memory_limitに達した場合はCakePHPsymfonyも処理が止まる
  • 処理に必要になるメモリの量はsymfonyもcakeもほぼ同様
  • 処理速度を厳密に比較するならば データ量によって順番は変動する
  • メモリの使用量を厳密に比較するならば
    CakePHP1.1 < symfony < CakePHP1.2
  • symfonyのsfDebugのメモリ使用量は実際の使用量から乖離している
  • ほどほどのデータ量の場合はCakePHP1.1のパフォーマンスがバランスが取れている

フレームワークの選択そのものがメモリの消費量を決定的に変えてしまう事はないでしょう。当然といえば当然ですが、実装内容に問題があるかどうかの方が影響は大きいと考えるのがよさそうです。

バージョン

PHP 5.2.6
MySQL 5.0.18
apache 1.3.34
symfony 1.0.14
CakePHP 1.1.19
CakePHP 1.2.0

測定方法

memory_get_usage

 /usr/local/lib/php/symfony/debug/sfWebDebug.class.php:      $total_memory = sprintf('%.1f', (memory_get_usage() / 1024));

memory_get_peak_usage

cake
 if (Configure::read() > 0) {
   echo "-- " . round(getMicrotime() - $TIME_START, 4) . "s --";
   echo sprintf("-- %.1fKB --",memory_get_usage() / 1024);
   echo sprintf("-- %.1fKB --",memory_get_peak_usage() / 1024);
   echo sprintf("-- %s classes --", count(get_declared_classes()));
   echo sprintf("-- %s vars --", count(get_defined_vars()));
 }
symfony
 sfContext::getInstance()->getController()->dispatch();
 echo sprintf("-- %.1fKB --", memory_get_peak_usage() / 1024);
 echo sprintf("-- %s classes --", count(get_declared_classes()));
 echo sprintf("-- %s vars --", count(get_defined_vars()));

テスト結果

データ取得無し
FW time(ms) usage(KB) peak_usage(KB)
symfony 433 2532.9 2765.8
CakePHP 1.1 330 2668.3 2722.9
CakePHP 1.2 632 4452.7 4507.9
取得データ100件
FW time(ms) usage(KB) peak_usage(KB)
symfony 747 3725.7 3950.1
CakePHP 1.1 700 2744.9 2800
CakePHP 1.2 700 4524.9 4580.6
取得データ50000件
FW time(ms) usage(KB) peak_usage(KB)
symfony 29290 5262.3 66270.2
CakePHP 1.1 32717 50395.9 52865.1
CakePHP 1.2 32552 49707.3 52185.4

補足

検証結果で気になるポイントがいくつかありますね。

  • CakePHP1.2が1.1と比較すると処理速度、メモリ使用量で肥大化しているように見える。
  • 取得データが多い場合は1.2のほうがパフォーマンスが良い。
  • symfonyはmemory_get_usageとmemory_get_peak_usageの開きが大きく、変数の開放などを工夫しているように見える。