独自開発の CMS で、編集完了したページを公開しようとするとエラーが発生しているようだった。
どうも AJAX で呼び出している PHP スクリプトがタイムアウトしているらしい。
ローカル環境で再現しようとすると、時間はかかるが公開処理は正常にできた。
該当記事をエディタで短くしていくと処理時間が短くなるので、何かしら記事を処理する部分が時間を食っているのはほぼ確実だった。
この CMS ではページを公開する際に、検索用のデータを生成しており、この時、自前の処理で html をパースしていた。
問題はこのパース処理だった。
応急処置として、自前処理ではなく DOMDocument の loadHTML メソッドを使用するようにして、業務に支障がない状態に出来たが、根本対策には html のパースを高速化する必要があった。
mb_ereg 系の関数を使用していたため、preg 系に修正してみたが、今度は Segmentation fault が発生した。どうもデータベースのトランザクション内で正規表現ライブラリをガッツリ使うとメモリが足りないらしい。mb_ereg 系に戻して、再度検討を行う。
よく調べてみると、正規表現を使っている部分は、タグ部分の切り出し時と、切り出したタグ部分の分解だった。タグ部分の切り出し時には mb_ereg に記事全体を渡しており、どうもここが怪しい。
タグ部分の切り出し処理を、正規表現から strpos/substr などの文字列処理関数に修正すると、すばらしい処理速度となり、対策を完了することが出来た。
PHP の正規表現処理は非常に便利なのだが、現時点では大きな文字列の処理には向いていないようだ。
今回のように、処理速度に問題があるようなケースでは、以外な方法のほうが結局速かったりするので、いろんな方法を思いつけるように準備して置かなければならない。