mod_mruby、mod_lua、mod_perl、mod_rubyのアーキテクチャの違いと性能

mod_mrubyやmod_lua、そしてこれまでApacheモジュールをスクリプトで書く場合に使われてきたmod_perlとの性能比較を行っています。

modとしてのアーキテクチャの差で処理系の性能差を埋める

処理系としての差ではなく、Apacheのmod_***としてのアーキテクチャの差によって、Apache上での性能が大きく変わる事が分かってます。Apacheはプロセス(スレッド)をプールしておいて、複数のリクエストに対しプロセスを再利用するアーキテクチャであるため、インタプリタのロードやライブラリの読み込み、さらにはスクリプトをコンパイルするタイミングを工夫すれば、Apache上では高速に動作させる事が可能になります。

例えば、mrubyはLuaより遅いと思われますが、mod_のアーキテクチャの工夫によって、mod_mrubyがmod_luaの性能を上回る事ができています。しかし、mod_perlもmod_としてのアーキテクチャはとても工夫しているように見えるのですが、ほとんど工夫していないmod_luaよりも性能が劣っているのです。

アーキテクチャの差と性能を比較

まずは、以下の表を見てみましょう。mod_***それぞれのインタプリタの読み込みのタイミングやコンパイルのタイミングをまとめた上で、同時接続数100総アクセス数100000の負荷をかけた場合の1秒間のレスポンス数を示しています。

性能の行は基本的にApache2.2で評価しましたが、mod_luaは2.2にはありませんので、Apache2.4系で性能測定を行った値は()で括りました。mod_mrubyやmod_helloは2.2と2.4両方で測定したので、それらの値を使ってApacheのバージョン間の差を読み替えて頂けると良いと思います。

それぞれのmod_***が行った処理は、全てのアクセスに対してHelloWorldを表示するだけの簡単な処理です。mod_helloはCでベタに書いたApacheモジュールです。

 

考察

基本的に、mod_***は外出しのインタプリタを呼び出すのではなく、Apache起動時にプロセスに拡張ライブラリと共にロードしておきます。

mod_perlのRegistryは初期化やライブラリを事前に行って、さらにスクリプトもコンパイルして機械語としてメモリにキャッシュしておくアーキテクチャをとっています。しかし、スクリプトを実行する度に状態遷移の初期化から処理するmod_luaのアーキテクチャよりも速度が出ていない(mod_helloやmod_mrubyから2.4と2.2の性能の差を考慮すると、mod_luaが2.2で動作すると5200ぐらいの性能がでると換算)事がわかります。PerlrunとRegistryの差はある程度出ていますね。

さらには、本実験においてはRegistryの性能よりもmod_rubyの方が性能が高いようです。

今回は、処理系としての差があまりでないようにHelloworld出力というシンプルなコードにして、mod_***としてのアーキテクチャの差による性能の差が見たかったのですが、ここまでmod_perlが遅いとそれの説明がつきません。

mod_perlでは、スクリプトを実行するまでにボトルネックになるような処理をしているのでしょうか。ソースを見ているのですが、まだそこまではおえていません。それとも、機械語のレベルでとても効率の悪いものになっているのか、はたまた全く違う所に理由があるのか。

うーん、これは引き続き要調査です。

「mod_mruby、mod_lua、mod_perl、mod_rubyのアーキテクチャの違いと性能」への1件のフィードバック

コメントは受け付けていません。