今日も適当ダイアリー

PHP や Javascript や Symfony、BEAR.Sunday などのWeb周りのことを中心に。それ以外のことも気まぐれに投稿します。

PHP5.4 で Symfony2 は速くなるのか?

Symfony Advent Calendar JP 2011 7日目です。
6日は @uechoco さんによる [Symfony2]入出力の文字エンコードを変換してみよう Symfony Advent Calender JP 2011 – 6日目- でした。

さて、@uechoco さんから「MongoDB JPにも所属している@madapajaさん」と紹介いただき、これは MongoDB ネタをやれってことかな?とか考えてしまいましたが、今回は PHP5.4 がらみのことを。

PHP5.4 は速くなっているらしいと風の噂で聞いたものの、Symfony2 は速くなるのかなと思ったので試してみました。
環境によって結果が異なると思いますが、今回は Symfony2 本体のテスト速度を計測してみます。
今回テストに用いた環境は下記の通りです。

サーバー さくらのVPS 512
OS Ubuntu 10.04.3 LTS
PHP
  • 5.3.8
  • 5.3.9 RC2
  • 5.4.0 RC2

PHP はすべて下記のconfigureオプションを用いてコンパイルしました。


--with-openssl \
--with-pcre-regex \
--with-zlib \
--with-mhash \
--with-xsl \
--enable-intl \
--enable-mbstring \
--with-mcrypt \
--enable-pcntl \
--with-libedit \
--with-readline \
--with-pear \
--disable-debug

PHPUnit をインストール。


$ ./php-5.X/bin/pear channel-discover pear.phpunit.de
$ ./php-5.X/bin/pear channel-discover components.ez.no
$ ./php-5.X/bin/pear channel-discover pear.symfony-project.com
$ ./php-5.X/bin/pear install phpunit/PHPUnit

最後に最低限の php.ini を設定します。


extension=apc.so

short_open_tag = Off
magic_quotes_gpc = Off

[Date]
date.timezone = Asia/Tokyo

念のためバージョンを確認。


$ ./php-5.3.8/bin/php -v
PHP 5.3.8 (cli) (built: Dec 3 2011 16:37:19)
Copyright (c) 1997-2011 The PHP Group
Zend Engine v2.3.0, Copyright (c) 1998-2011 Zend Technologies

$ ./php-5.3.9RC2/bin/php -v
PHP 5.3.9RC2 (cli) (built: Dec 3 2011 16:45:05)
Copyright (c) 1997-2011 The PHP Group
Zend Engine v2.3.0, Copyright (c) 1998-2011 Zend Technologies

$ ./php-5.4.0RC2/bin/php -v
PHP 5.4.0RC2 (cli) (built: Dec 3 2011 16:55:22)
Copyright (c) 1997-2011 The PHP Group
Zend Engine v2.4.0, Copyright (c) 1998-2011 Zend Technologies

いざ、テスト!

テストは、symfony/symfony - GitHub から clone して、vendors.php でベンダーファイルをインストールしたら、phpunit と叩くだけです。
今回は、PHP 5.3.8 → 5.3.9RC2 → 5.4.0RC2 の順でテストを実行させ、それを11周実行することにしました。そのうちの、1サイクル目を除いた10サイクル分の結果を比較してみます。(なお、テスト間は 5秒の sleep を入れてあります。)

では実行結果です。じゃじゃーん。
PHPUnit で表示される秒数とメモリ(Mb)の平均です。

 Time (Sec.)Memory (Mb)
PHP 5.3.8 19.6 264.0
PHP 5.3.9RC2 19.0 191.5
PHP 5.4.0RC2 14.2 136.8

結果は明白ですが、一応グラフも。数値が低い方がベターなのは言うまでもありません。

PHP 5.4.0 の方が時間、メモリ共に効率がよくなっているようです。PHP 5.3.8 と 5.3.9 の比較では時間はさほど変わりませんでしたが、メモリの使用量は減っていますね。
構成や設定など環境や使い方によって結果は異なってくるかと思いますが、PHP 5.4 のリリースも楽しみにしたいと思いました。

PHP 5.4.0RC2 で謎のセグフォ

PHP 5.4.0RC2 でテストを実行したら、テストの途中で Segmentation Fault で落ちるという事態が発生しました。
あーだこーだと悩んだ挙句に下記の変更で無理やり回避出来ることがわかりました。

// src/Symfony/Component/HttpKernel/Kernel.php
:

// 530行目あたり
protected function initializeContainer()
{
$class = $this->getContainerClass();
$cache = new ConfigCache($this->getCacheDir().'/'.$class.'.php', $this->debug);
$fresh = true;
if (!$cache->isFresh()) {
$container = $this->buildContainer();
$this->dumpContainer($cache, $container, $class, $this->getContainerBaseClass());

$fresh = false;
}

usleep(0); ///< これを追加

require_once $cache;
$this->container = new $class();
$this->container->set('kernel', $this);
:

もちろんこれは根本的な解決ではなく、そして Symfony2 のバグでもなく、PHPか、そのモジュールか、環境によるバグだと思われます。
とりあえず、Symfony2 のバグでは無さそうだ、という事を確認しただけで調べていないのですが、とりあえず、私の環境では上記の行にシステムコール(というのが正しいのか分かりませんが、sleepとかfopenとか)があるとセグフォらない、という状況でした。

(追記)
この問題が発生したのは、SecurityBundle の機能テストのみです。(具体的には下記テストの実行でセグフォ)
src/Symfony/Bundle/SecurityBundle/Tests/Functional/FormLoginTest.php
src/Symfony/Bundle/SecurityBundle/Tests/Functional/LocalizedRoutesAsPathTest.php
src/Symfony/Bundle/SecurityBundle/Tests/Functional/SecurityRoutingIntegrationTest.php

さあ、明日の Symfony Advent Calendar JP 2011、第8話 は @yuchimiri さんです!
お楽しみに!