-オープンソースのSNSエンジン OpenPNEプロジェクト-

OpenPNE3.6beta11のORMを変更する実験をしました

11 / 08 火曜日 2011

OpenPNE3にある現状の課題の一つにパフォーマンスの問題があります。OpenPNE3がサーバーに要求するスペックはOpenPNE2よりも高く、OpenPNE3へのアップグレードを敬遠する理由の一つとなっています。そこで、もしOpenPNE3で使用しているDoctrine1を別のORMで置き換えるとどの程度パフォーマンスが改善されるかを実験しました。

環境

basho1 (芭蕉1 / Webサーバ)
Intel Core 2 Quad Q8400S 2.66GHz / 4GB Memory
CentOS 5.5
PHP 5.3.3 / APC 3.1.9 / XHProf 0.9.2
Apache 2.2.3
basho3 (芭蕉3 / DBサーバ)
Intel Core i5 i5-760 2.80GHz / 8GB Memory
CentOS 5.5
MySQL 5.1.53

詳細は http://d.hatena.ne.jp/openpne/20110823/1314078181 を参照して下さい。

比較したORM

  • Doctrine 1.2.4 (OpenPNE3標準)
  • Propel 1.6.2
  • php-activerecord 1.0
  • Doctrine 2.2.0-DEV

DBサーバにメンバーが380,000人登録されている状態で、検索クエリを設定していない状態の「メンバー検索」ページにてXHProfを使用して計測しました。

比較のために使用した修正版OpenPNE3のソースコードは下記URLから入手できます。

結果

処理時間

doctrine1 propel1.6 php-activerecord doctrine2
Total Incl. Wall Time (microsec) 885,274 457,233 477,260 383,231
Total Incl. CPU (microsec) 784,880 367,944 387,942 332,949

処理時間では Doctrine1 > php-activerecord > Propel > Doctrine2 の順となりました(短いほど良好)。グラフからも分かるとおりDoctrine1は圧倒的に時間が掛かっています。一方、それ以外のORMではあまり変わらない結果となりました。
処理速度の比較グラフ

メモリ使用量

doctrine1 propel1.6 php-activerecord doctrine2
Total Incl. MemUse (bytes) 21,630,856 20,403,448 14,256,808 16,358,240
Total Incl. PeakMemUse (bytes) 21,947,888 20,609,392 14,485,672 16,603,624

メモリ使用量では Doctrine1 > Propel > Doctrine2 > php-activerecord となりました(少ないほど良好)。PropelがDoctrine1と同じくらいのメモリ使用量になるのは予想外でした。ただ、MemUseとPeakMemUseの差はどのORMでもほとんど変わらないため、メモリ使用量の改善はORM以外の処理でオブジェクトが解放されるように工夫する必要がありそうです。
メモリ使用量の比較グラフ

Function call数

doctrine1 propel1.6 php-activerecord doctrine2
Number of Function Calls 184,078 76,753 87,364 69,613

Function call数についても比較しました。これは Doctrine1 > php-activerecord > Propel > Doctrine2 の順でした(少ないほど良好)。ここでもDoctrine1が特に悪い結果となりました。
Function call数の比較グラフ

変更に要する作業量

OpenPNE3ではプラグインが現在 plugins.openpne.jp に登録されているだけでも80個近く存在し(2011年11月現在)、ORMを変更した場合はこれらの内データベースを使用するほぼ全てのプラグインで修正を行う必要が出てきます。そのため、ORMを変更する場合は単純にパフォーマンスが良いというだけでなくDoctrine1からの移行のし易さも考慮する必要があります。

Propelは、現在Doctrine1で使用しているのビヘイビアやi18nに相当する機能を備えており、sfPropelORMPlugin によってsymfony1.4環境でも問題なく使用することができるため、他のORMと比べると格段に移行し易いです。ただし、それでもschema.ymlの変更やモデルクラスの大幅な修正が必要になるため、移行作業はかなりの時間を要します。参考までに、今回の実験のためにメンバー一覧のページをPropel向けに修正するために15日(通算56時間)ほど掛かりました。

php-activerecordは、現時点でsymfony1.4向けのプラグインが提供されておらず(今回はORMの比較のために作成した sfActiveRecordPlugin を使用しています)、今までのようなsymfonyのタスクによるテーブルの作成やfixtureの挿入は一から実装する必要があります。また、i18nに相当する機能はORM側で用意されておらず、どのように対応するかが課題になります。

Doctrine2は、symfony1.4向けプラグインとして sfDoctrine2Plugin が提供されていますが実質メンテナンスされておらず、最新版のDoctrine2には対応できていません。i18nはORM側の機能としては用意されていませんが、DoctrineExtensions などを利用することでそれに相当する機能を使えるとのことです(ただし今回の検証ではうまく動作しなかったため使用しませんでした)。

このような現状から、単純に移行に掛かる作業量だけを考えた場合はPropelがベターな選択肢となります。

# もちろんORMを変更する必要がなければ作業量はゼロです :)

まとめ

処理時間 メモリ使用量 ORM変更の作業量
Propel
php-activerecord ×
Doctrine2

結果をまとめると上記の表のようになりました。全体的なパフォーマンス面ではDoctrine2、移行のための作業量を考慮するとPropelが良い選択肢となりそうです。いずれにしても処理時間では最大で4〜5割の改善は見込めることが分かりました。

結果データなど

今回の実験で得られたXHProfのデータを下記URLで公開しています。

Doctrine1:

Propel:

php-activerecord:

Doctrine2:

トラックバック:1

ピンバック from OpenPNE 3.7 開発仕様について。【beta版】 - besocial.jp 11-11-11 (金) 13:06

[…]  そして、OpenPNE3では、以前にもopenpne.jpのブログで「OpenPNE3.6beta11のORMを変更する実験をしました」という記事がありましたが、OpenPNE3が抱える問題としてスピード(レスポンス)が遅い […]

ページの先頭に戻る