キャッシュのおさらい

フレームワークの性能を向上させる手掛かりとして、キャッシュについて考えてみます。

フレームワークによるパフォーマンス低下

フレームワークを利用する場合、パフォーマンスが犠牲になることはよくあります。フレームワークを設計する側からすると抽象化してなるべく多くのサービスで利用できるような多様性を整えたいと考えると思います。結果として、ハードコーディングすれば素早く動作するケースでも依存を外に出してメンテナンス性を向上するといった工夫がとられています。バーターでパフォーマンスを失うので、冗長性の高いフレームワークベンチマークテスト等で優位に立つことはあまりないと思います。また、その必要もないでしょう。多様性を実現するために行われる処理分、そうでないシステムよりハンデを負うのは当然と言えます。ノーフリーランチ定理ですね。

特化かキャッシュか

フレームワークを選択する際に、サービスに特化したフレームワークを利用することができるなら、多様化によるパフォーマンス低下は防げると思います。実際、限られた用途ならすばらしいパフォーマンスを示すフレームワークは多くあります。そのフレームワークが元からサービスにマッチしているか、あるいは完全にカスタマイズして運用できるのなら問題ありません。
ところが多くの場合、何かに特化したフレームワークがいくつかのサービスにそのまま適用できるということは難しいです。(それは特化とは言わないですしね)そこで、汎用的に運用できる多様化されたフレームワークの利用が想定されるわけですが、前述したようにそういったフレームワークにはいくつかパフォーマンス低下を招く要因があります。
しかし、幸いにキャッシュを利用すると、特化されて作られたフレームワークと同様のパフォーマンスを確保することが可能です。理論上、ページキャッシュが許されるコンテンツならどんなフレームワークでもほとんどパフォーマンスは変わらないでしょう。
問題になるのは、単純にはキャッシュ出来ないケースをどこまで効率よくキャッシュできるかという部分にあるように思います。
多様化された汎用性の高いフレームワークをパフォーマンス低下させずに利用するためにはキャッシュの利用が不可欠になると思います。

中間育成コードというキャッシュ

フレームワークと言ってよいかどうか、smartyはテンプレートのパース結果をPHPコードにして保存します。PHPTALもそうです。この方式を取ると、柔軟なテンプレート様式をもっていても、テンプレートのパースによるオーバーヘッドをなくし、ほぼ純粋なPHPコードの実行に費やすことができるようになります。実際、テンプレートエンジンを使ってパフォーマンスを引き上げる場合はこの方式が解であるように思えます。

DBクエリのキャッシュ

データベースは高負荷な状態とそうでない場合では処理速度に大きな差が出ます。また、データベースに変更が発生していなければ、同一クエリに対する結果は同一です。そのため、DBクエリはキャッシュに向いていると言えると思います。
実際、データベースエンジン側でも更新を監視してクエリキャッシュを行うように設定できますし、クエリ結果をmemcachedなどに保存して複数サーバや複数プロセスで結果を共有するという方法も優れた方法かと思います。

設計レベルでのキャッシュ

まとめると、ページキャッシュのように単純にキャッシュ出来るものは(静的ディプロイも含めて)それをやればいい。DBクエリでのキャッシュもテンプレートパーサーの中間コードの育成もロジックは極めてシンプルで汎用性の高いものなので既存のコードで十分な効果が期待できると思いますのでそれも措置しましょう。
さて、残るはフレームワーク設計レベルでのキャッシュについて考えてみたいと思います。ベンチマークテストにはなかなか現れてきませんが、ページキャッシュすることができないようなページが最近では増えてきているので、単純ではないがページキャッシュ並みのパフォーマンスを出せる仕組みが必要になってきていると思います。考え方自体はWebの初期から考案されているものなので新しくはないのですが、フレームワーク側が積極的にキャッシュフレンドリな設計を行っているケースはまだ少ないような気がします。おそらく、個々のフレームワークやテンプレートエンジンのターゲット層との兼ね合いで安全なところだけ実装している状態だと思いますので、この部分は利用者側で想定する必要があるのかもしれません。

続きはまた・・・後日。