Jul 30, 2007

WebSig 24/7の参加報告 + MT4の高速化あれこれ

WebSig24/7というイベントに参加させていただいた。私の発表資料はそのうちどこかで公開されると思うが、私はMTOSとそれに関連してGPLまわりの話題を話させていただいた。

この手のイベントに参加するのは初めてなので、私ともあろう者が*1「空気読む」のに若干神経使ってしまった。あえてこの夏一番暑かっただろう日に、あえて東京の中でも緑化不足で無駄に気温の高い秋葉原に足を運んでくるという連中参加者がどういう種類の人たちなのかまるで分からなかったからだ。

*1 「空気を読まないし読もうともしない、そんな私が(常日頃にはあるまじき配慮をもって)」ということである。コメント欄のように体調を崩す読者もいらっしゃるようなので製造物に対する責任を果たすべく念のため註とした。

この際はっきり言わせてもらう、

「だいたいおまいらマジメ過ぎなんだよっ!!」

と。休憩10分だけで40分の講演を4本+質疑応答セッションを行うということの「非常識」を誰も認識していない。世間の標準というのは、20分講演+10分質疑のセットを4本まとめたくらいが1セッションで、そのセッションの合間には30分程度のブレークを入れるもんだ。まれに1セッションに6セットくらい詰め込まれると、参加者がぶーたれるか、4セット目あたりで自主的にブレークタイムに突入する参加者が現れるもんだ。参加者が大半がろくに話を聞いてなくてしょうがなく座長が無理矢理質問する、そのイタさ加減が「会議」の醍醐味ってもんなんだ。

「講演中に無駄口くらいしやがれ、内職しやがれ、内職してプラグインの一つも書きやがれ」

と私は言いたい。だけど、そういうマジメさも嫌いじゃないのでまた機会があったら呼んでください。ペコリ。

ついでなので、他の話者の話にツッコミを入れておこうと思ったけれど、私を含めてnot so technicalな内容だったので止めておく。それだけだとなんなので、再構築うぜぇからやっぱWordPressだよねっていうWeb屋は...いや、まぁ何だ、ちゃんと考えようぜ。 (Junnama Online (Mirror))にツッコミというか釣られてみる。

私がサクッと思いつく、高速化のアイディアとしては以下のようなものがある。

  1. 並列に実行する
  2. 高速なテンプレートエンジンを用いる
  3. データの局所性を利用する
  4. テンプレートを最適化する

まず、1.について。MT4の採用しているTheSchwartzやMemcachedを使った実装では、再構築を非同期に、かつ並列に行うことで高速化を達成できる。ただし、並列化の恩恵を受けられる環境を使える人は限られている。これはこれで高速化への解になっているのだが、シングルスレッドでの実行性能を追求することを先送りする解でもあって私のような最適化厨への受けは必ずしも良くない。

2.について。MTの場合、テンプレートを読み込み、パーズして内部的なデータ構造を作り、次にそのデータ構造を元にデータベースから必要なデータを読み込んで...(中略)...最終的にHTMLをレンダリングする、ということを行う。これを高速化するには、まあ安直に考えて以下の三つの方法がある。

  • MTの静的生成では、パーズ結果は毎回捨てられる。だからもし、その内容をキャッシュする機能を備えたテンプレートエンジンを作れば、解釈実行のオーバーヘッドは小さくできる。
  • また、MTの静的生成では、前処理部分はSyntax Treeのようなものを生成するだけでコンパイルせず(メソッド名はcompileだが)、後処理部分はSyntax Treeをトラバースしながら現れた変数タグ・コンテナタグに対応するハンドラメソッドをルックアップして実行している。簡単に言ってしまうとこれはテンプレート言語のインタプリタの実装である。この実装を捨ててしまい、コンパイルしてPerlプログラムを生成し、後処理ではそれをevalだけで済むようにすれば、解釈実行のオーバーヘッドを小さくできるし、コンパイル結果をキャッシュしやすくもなる。
  • また、MTのダイナミックパブリッシングでは、テンプレートのコンパイル結果(これはPHPプログラムになる)をキャッシュすることができる。だからもしコンパイル結果を解釈実行するコストがPerlとPHPで変わらないのだとすると、ダイナミックパブリッシングの方がオーバーヘッドが小さい。つまり、静的生成の時にもダイナミックパブリッシングのバックエンドをテンプレートエンジンとして使えば高速化できる。ただし、プラグインなどをPHPで書く必要があり、本質的な解にはならない。

3.に関して。2.に書いたような最適化ができたとしてもコンパイル済みテンプレートを解釈実行する際に、データベースを三三五五アクセスするのは効率が悪い。なぜなら、single-threaded codeの途中にシステムコールがあるとそれだけで遅くなるから。だから、テンプレートを解釈実行する前に使用するであろうデータの大部分をメモリ上にキャッシュしておき、それを再利用するようにすれば速くなる。ソフトウェアパイプライン的な最適化ね。

4.についてはjunnnamaさんが書いていることも部分的な解になっている。もう少し一般化すると、テンプレート「プログラム」の局所最適化を行うということ。例えば、プログラムの共通部分式を自動的に、あるいは人手を借りて検出することができれば、再計算を避けるためにキャッシュすることができる。この方法は、ターゲットプログラムが複雑であるほど困難だが、簡単なヒューリスティックで大きな効果が得られる場合も多い。

まあそんな感じ。あまり真面目に考えていないけど。

About Me

My Photo

つくばで働く研究者

Total Pageviews

Amazon

Copyright 2012 Ogawa::Buzz | Powered by Blogger
Design by Web2feel | Blogger Template by NewBloggerThemes.com