LAMP vs. LAMP──mod_perlとmod_phpのパフォーマンス比較

ダイナミックWebサイトの構築ではPerlとPHPが広く使われている。なにしろ、LAMPスタック(Linux、Apache、MySQL、Perl/PHP/Python)に含まれる「P」の3分の2なのだ。それでは、通常のWebプログラミングでは、mod_perlとmod_phpのパフォーマンスはどちらがよいのだろうか。ちょっとしたテストをしてみたので報告する。

テストは、一般にWebホストとして提供されていると思われる環境で行った。テストで使用したCompaq ProLiant DL380の仕様とソフトウェアは、次のとおり。

700MHz Pentium III
1GB RAM
Red Hat Enterprise Linux 3
Apache 2.0.46
MySQL 3.23.58
Perl 5.8.0
PHP 4.3.2

テストに使ったPerlとPHPのプログラムは、それぞれ、HTMLを生成するものとMySQLデータベースを読んで更新するものの2本で、出力はもちろん同じ。ロジックもできるだけ近似させてある。

HTML生成テストでは、1から1,024までカウントしながらHTMLを1行画面に書き出すプログラムを、次の5とおりの負荷条件で実行した。

1 HTTPリクエスト

100 HTTPリクエスト(順次)
100 HTTPリクエスト(10本ずつ同時処理)
1000 HTTPリクエスト(順次)
1000 HTTPリクエスト(10本ずつ同時処理)

MySQLテストでは、5,000件のレコードを含むテーブルを読んで更新するHTTPリクエストを1つ実行した。MySQLとのやりとりには、標準PHPインタフェースとPerl DBIを使った。テストに使ったテーブルの構造は次のとおり。

+----------+----------+------+-----+--------+----------------+
|フィールド|  タイプ  | Null |キー | 既定値 |  その他の特性  |
+----------+----------+------+-----+--------+----------------+
| id       | int(11)  |      | PRI | NULL   | auto_increment |
| junktext | char(30) |  可  |     | NULL   |                |
+----------+----------+------+-----+--------+----------------+

5,000件のレコードは、次のように初期化した。

+-------+--------------------------------+
| id    | junktext                       |
+-------+--------------------------------+
| 1     | XXXXXXXXX0XXXXXXXXX0XXXXXXXXX0 |
+-------+--------------------------------+

テストに使ったプログラムは上記のテーブルからレコードを読み、junktext列を小文字に変換して書き戻す。したがって、このテストでは、データベース・ドライバーの特性と、PerlとPHPのオーバーヘッドを測定することになる。

LAMPスタックのコンポーネントはRed Hatが配布しているものをそのまま用い、チューニングはしなかった。利用者がWebホストのシステム・コンポーネントを変更できることは滅多にないからだ。コードを見てみたい読者のために、Perl HTMLテスト・コード、Perl MySQLテスト・コード、PHP HTMLテスト・コード、PHP MySQLテスト・コードを公開しておく。

テスト結果

HTML

ApacheBenchプログラム(バージョン 2.0.40)――標準Apacheパッケージに含まれているツールで、HTTPリクエストが処理され結果が戻るまでの時間を測定し総和と平均を表示する――を使い、スクリプトを3回実行して平均を取った。テストは、すべて、内部ネットワーク上で行っている。したがって、クライアントもサーバーも、絶えず変動するインターネット環境からの影響は受けていない。

比較の基準とするため、Perlプログラムを通常のCommon Gateway Interface(CGI)プログラムとした場合もテストした。CGIはダイナミックWebコンテンツを制作するために最初に使われた手法の一つであり、今でもWebの魔法は多くのCGIプログラムが支えている。しかし、リクエストごとに新しいプロセスを生成しPerlインタープリターをロードするため、大量のメモリーを消費するという欠点がある。これに対して、mod_perlのインタープリターはApacheの中にある。mod_perlもmod_phpも、そのページを処理しているApacheプロセスの中で動作するため効率的に実行できるのだ。

Perl CGI、mod_perl、mod_phpのテスト結果は次のとおり。第1列で、HTTPの後の数字は、そのテストにおけるリクエストの数。その数字の後にあるcは、そのテストでリクエストが10本ずつ同時処理されたことを表す。時間の単位はすべて秒(小さい方がよい)である。

HTML生成テスト
  CGI mod_perl mod_php
HTTP-1 0.1607 0.2392 0.1711
HTTP-100 16.6229 2.4346 1.6607
HTTP-100c 16.4683 1.8337 1.5694
HTTP-1000 160.8190 16.2288 16.6460
HTTP-1000c 161.1753 17.2127 15.6850

MySQLテスト
  CGI mod_perl mod_php
MySQL-rw 1.8157 1.4807 1.2189

テスト結果のまとめ

MySQL

まず、言語が備えるオブジェクト指向機能の使用、サードパーティーのモジュールまたはセッションの混入、ストレージ・タイプの違いが結果に影響した可能性があることをお断りしておく。

今回のテスト結果からは、多くの一般的Webプログラミングで、PHP(mod_php)のパフォーマンスはPerl(mod_perl)よりもわずかに高いと結論される。HTML生成実験のほとんどで、またMySQL実験で、PHPはPerlをわずかだが凌いでいる。ただし、MySQLの結果はインタープリターというよりもデータベース・ドライバーの特性を反映したものだろう。

予想どおりのことだが、標準CGIに比べると、mod_perlもmod_phpも圧倒的なパフォーマンスを示した。標準CGIはスケーラビリティーが悪いだけでなく、同時処理をしても効果がない。ちょっと負荷が高くなるだけでサーバーはお手上げになるだろう。

mod_perlには面白い特徴がある。その一つは、Perlプログラムをコンパイルし次回の使用に備えてメモリー上にキャッシュする点。したがって、負荷が高まるにつれパフォーマンスが良くなる。たとえば、今回のテストでは前述のように同じテストを3回繰り返して平均したのだが、後続の2回のテストは常に最初のものより速くなった。時間をおいてテストすれば、キャッシュはクリアされ、mod_perlはプログラムを再度コンパイルすることになる。図に示した値は3回連続テストによるものである。

また、mod_perlはPerlコードをApache構成ファイルに埋め込むことができ、ダイナミック・サーバー構成の選択肢が広い。PHPに同様の機能はない。

PHPは、テスト方法にかかわらず一貫したパフォーマンスを示した。初めからダイナミックWeb言語として設計されているため、その点で優れた特性を持っているのである。

チューニングが可能であれば、PerlもPHPも、Apacheで使うときのパフォーマンスを改善する方法がいろいろある。Perlでは、FastCGIモジュールがあるし、PHPキャッシュ・アクセサレーターには、プロプライエタリのもの、無償のものオープンソースのものがある。ただし、高度なオプションであり、設定は難しい。

勝負は互角

PerlもPHPも、Webアプリケーションを作るための堅牢で強力な言語だ。小規模から中規模クラスのアプリケーションを作る限り、実感できるようなパフォーマンスの違いはないだろう。しかし、巨大なトラフィックが想定されるアプリケーションでも、同じとは限らない。多くの要因が絡んでくるからだ。

結論――PerlでもPHPでも、どちらでもよい。

NewsForge.com 原文