symfony のルーティング処理のダイエット
prod モードではデフォルトで、ルーティングの設定のみでなく、設定から生成される sfRoute クラスでコンパイルを行った状態のインスタンスがシリアライズされ、キャッシュされます。
したがって、prod モードでは実行時のコンパイル処理のオーバーヘッドは気にしなくてもよさそうです。
ただし、最大でルーティング設定の個数分のマッチング処理が行われることと、ルーティング設定 1 つにつき 1 つの sfRoute オブジェクト(または sfRoute の派生オブジェクト)が必ず生成されて配列としてすべて保持していることから、無駄にルーティング設定の個数を増やすことはそれだけでメモリを無駄に消費していたり、symfony の実行速度を遅くしてしまいます。
パターンに * を使うか、変数にマッチする条件を正規表現で上手く指定してやることで、複数のパターンを 1 つにまとめられる可能性があります。内部的には最終的に preg_match が実行されることには変わりないので、積極的に正規表現を使ってパターンをまとめるようにすると良いのではないでしょうか。
例:
- /Dir1/page/ja
- /Dir1/page/en
という 2 つのページがあって、1 つのアクションで内部的に ja と en を拾って切り替える場合
pat1: url: /Dir1/page/ja param: { module: module1, action: action1, lang: ja } pat2: url: /Dir1/page/en param: { module: module1, action: action1, lang: en }
を、
pat1: url: /Dir1/page/:lang param: { module: module1, action: action1 } requirements: { lang: ja|en }
としても同等です。(あまり面白い例でなくてすみません・・・。)
sfRouteのコンパイル済み正規表現の確認
実際にパターンがどのような正規表現にコンパイルされているのかを確認しながら、routing.yml の最適化を行うとよさそうです。
ルーティングの確認には、symfony コマンド「app:routes」を使用します。
$ ./symfony app:routes frontend >> app Current routes for application "frontend" Name Method Pattern homepage ANY / route1 ANY /Dir1/Dir2/:param1/:param2 :
この app:routes タスクに、ルーティング設定名をオプションで指定すると、そのルーティング設定の詳細(コンパイル済み正規表現を含む)を確認することができます。
$ ./symfony app:routes frontend route1 >> app Route "route1" for application "frontend" Name route1 Pattern /Dir1/Dir2/:param1/:param2 Class sfRoute Defaults action: 'actionname' module: 'modulename' : Regex #^ /Dir1 /Dir2 /(?P<param1>param\d) /(?P<param2>.*) $#x :
※Jobeet 5日目でも、ルーティングのこのデバッグについて触れられていますね・・。
※→symfony 1.x legacy website Route Debugging のところ。