Laravelのオートローダーが遅いというツイートはアンフェアだ

タグ: Laravel3   Laravel4   PHP  

一回ならまだしも、時々定期的にツイートされるのが、Laravelのオートローダーは遅いというものです。

例えば「Laravelが遅い」というのであれば、まだ分かります。なぜならフレームワークを変えて、同じようなコードを書き、その実行結果が前のフレームワークよりも体感的に明らかに遅い場合、その人は「Laravelは遅い」と書くでしょう。(Laravelの名誉のために書きますが、ミドルクラスのフレームワークの中では、機能的にそれほど高くはなく、単純なフレームワークのため、速度的に遅いということはありません。)ところが、オートローダーだけを取り上げて遅いと指摘されるのです。

ある人は、ベンチマークで速度を計測するでしょう。(たいてい現実離れしたコードです。)ある人は実行のコールマップを基にしてして判断するでしょう。

理由を示す

ツイートは基本短い文章です。短い文章であることを前提に発達したサービスです。ですから、通常は短く良いのです。

ですか、何かを判断するなら、その前提も一緒につぶやくべきでしょう。例えば、「どこそこのコンビニはまずい」と書けば、そこのコンビニで扱っている食品全体に対するイメージを低くすることになります。「これを購入したけど、味が薄すぎてまずい」くらいは書くべきです。

先日、あるパンメーカの菓子パンを購入しました。一口食べたらほとんど味がしません。甘くありませんし、アーモンドの香りを謳っているにしてもそんな香りもしません。そこで、もう一口食べてみました。そしたら苦味が口の中に広がりました。

裏返してみたら、明らかに焦げすぎです。すぐにコンビニで返品しようとしましたが、レシートを捨ててしまったので、メーカーのサービスセンターへ連絡しました。仙台で作成された商品だったそうですが、近くの新潟工場のちょっと偉い人が謝りに来ました。

それをツイートしたときは、ちゃんとまずかった理由も書きましたし、後の対応も良かったことも書きました。ネットは公共の場です。どんな発言でも多少の影響力はあります。ですから、どこかに不利になるような発言をするのであれば、せめて何があったとか、そう考えた理由を添えるべきです。

Laravelのオートローダーについて一番推測されるのは、ネット上にある古いコールマップを見ての発言でしょう。私も見た覚えがありますが、随分前のものでした。(比較されているフレームワークのバージョンは皆だいぶ前のものでした。)しかし、そのマップと一緒に示されていた、ベンチマークではLaravelはライトウェイトのPHPフレームワークには及ばないものの、ミドルクラスのフレームワークでは最速でした。

情報が古く役に立たないものであるとは思いますが、もしこれを基にして発言したのであるとするなら、せめてリンクを張っておくとか、これをみて判断したという一言を添えるべきでしょう。

オートローダーはどこも似たようなコード

オートローダーのクラスを比べてみれば、どこのフレームワークでもたいてい同じようなコードになっています。

ファイルで定義されているオートロード先のディレクトリーやクラスとファイルパスのマップに基づいてクラス名から定義してあるファイルを推測し、includeかrequireで読み込む仕組みです。

そうしたクラスパスの定義は最初に読み込まれ、配列で保存され、未ロードのクラスがあれば、オートローダーが配列を探すか、クラス名を基にファイルが存在しているだろうと推測されるパスの存在をチェックして、見つけたものを読み込みます。

仕組みはほとんど同じです。高度で便利なオートロードクラスを提供すれば、仕組みも複雑になり、存在のチェックにかかるファイルアクセスなどのオーバーヘッドのため、遅くなります。

つまり、Laravelだけ素晴らしく高度で便利なオートロード機能を持っており、そのためにオーバーヘッドがかかり遅いというのであれば、それは納得できます。しかし、Laravelのオートロードの機能は「月並み」です。他のフレームワークと大差がなく、コードを見てみても複雑なことをしているわけでありません。むしろシンプルです。

ローディング時間

オートローダーの実行時間にファイルのロード時間が含まれているのであれば、読み込むファイルの数や大きさで、オートローダーの実行時間は変わります。

これはクラスの設計に関わります。しかし、よほど遅いフレームワークでもない限り、ローディング時間を考慮してクラスの設計は行わないでしょう。通常は機能に基づいて行われます。

その結果、オートローダーの実行時間で差があってもおかしくはありません。オートローディングを採用しない古いライブラリーなどは、「一度に必要なもの」をロードすることで早くする努力をしていました。この方法はファイルアクセスにかかるオーバーヘッドは減らせますが、余計なコードも読み込むため読み込み量が増えます。

クラスのオートロードは適切に分割されたクラスを必要に応じて読み込みます。ですから、余計なコードを読み込む量は減りますが、ファイルの論理的なアクセス回数は増えます。

そのクラスの保存先のデバイスやアクセス特性が異なれば、実行時間は影響を受けるでしょう。簡単に言えば、私のコンピューターとあなたのコンピューターでは同じコードを実行しても同じようなローディングの結果がでるとは限らないという事です。そして、あなたの開発環境と、実働環境でも差が出るでしょう。

そうしたハード依存で差が出る部分があるのに、それをクラスファイルの大きさと数を調整して、最適解を探す努力をするフレームワークはまず存在しません。

ましてや、コアの部分だけ調節しても、私達が書くコードは千差万別です。個人のクラスの作り方でも、コード上のオートローダーで費やされたとみなされる実行時間は変化するでしょう。

フレームワークの速度

Googleの検索エンジンが、サイトの対応速度も考慮するという事実が明るみに出てから、やたらにフレームワークの速度を追い求める風潮が出てきました。それはそれで正解です。

ですが、本当にアクセスを集める「大きな」サイトで「最速」のフレームワークが使用されているかと言えば、そうではありません。レスポンスを決めるのは何もフレームワーク自体の速さだけではないからです。大きなサイトであれば、それなりにお金をかけ、別の手段も使用することで早くできます。

ですから、多少遅くても使える開発者の多いフレームワークが利用されます。なぜなら、実行速度ではなく、開発速度のほうがコスト的には高いからです。よほどダメなシステムでない限り、多少のお金をかけることで実行速度は上がりますが、開発速度は開発者の人数や能力、スキルによります。そのため開発速度を上げようとするなら費やすお金は多少ではすみません。

個人で開発する場合も、開発速度は関係します。Laravelフォーラムで速度が取り上げられているものがありますが、そこでも速度には実行速度と、開発速度があり、Laravelでは実行速度も早いし、開発速度も早いという話が出ています。これはいささか身びいきのところがあるとはいえ、開発のしやすさで多くの人が支持し、急速にシェアを伸ばしているのは事実でしょう。

それでも個人で開発している人が、実行速度も上げたいのかも知れません。Laravelが全体的には早めのフレームワークであっても、「オートローダー」がある資料で遅いと示されているので、受け入れられないのかも知れません。

私は実行速度の面で言えば、特定の一部分の速度を問題にするより、全体的な速度を考慮します。皆さんはどうでしょう。

そして重要なことに、大抵のフレームワークは私達が個人でサイトを構築する場合、十分な能力を持っています。私の作成したLaravelサイトのアクセス数は一分間に一ページもありません。例えば月に100万ページアクセスがある場合でも、1,000,000÷30日÷24時間÷3,600秒で、0.38580です。一秒に一回もアクセスがありません。それなのにこれは一秒に1000回アクセスできる、あれは1100回アクセスできるという能力の数字には、たいてい意味がないのです。

純粋にサイトの対応時間を短くしたければ、ファイルキャッシュを上手く使用するとか、CSSやJavascriptをまとめるとか、画像をまとめる、小さくする、使わないとか、既に確立された手段を取るほうが有利ではないでしょうか。また、サーバー自体を早くするとか、CDNを採用するとかも考えられます。

こうした高速化への努力が無駄になるほど、クラスのオートローダー自体が遅いというのはまずあり得ないでしょう。

Macの特殊事情

だいぶ前にMac上だけでLaravelが遅いという話題がよく出ました。

結局、PHP界で有名な人がフォーラムで「調べたけど、Laravelのせいじゃないよ。MacのOSでマシン名(ドメイン名)のサフィックスで特定のやつを使っていると、遅くなるんだ。」と回答後、同じような投稿は見かけなくなりました。

Mac使いの使いの方々が自分で対応したのか、それともOS自体がバグフィックスされたのかは知る由もありませんが、古いOSをそのまま使っているのであれば、この障害にひっかかっているのかも知れません。

でも、オートローダーという限られた部分のスピードではありませんよね。

もっと情報を

つまるところ、私は現在Laravelを応援していますが、もっと良いフレームワークがあれば、そちらを応援することになります。固執はしていません。ですから、もしLaravelのオートローダー自体が本当に遅いのであれば、それで構いません。

現在Laravelを選んでいる人は、オートローダーの速さでフレームワークを選定するような馬鹿な人はいないでしょう。

ですが、「オートローダーが遅い」というだけの情報は、誤解を呼び起こしますし、PHPフレームワークを選定している人達に悪い印象を与える「ブラックプロパガンダ」になっています。これだけをツイートし、情報を流すのはアンフェアです。

ですから、遅いのであればせめてどの記事を読んだとか、こうした状況に出会ったとか、多少は限定できる情報を加えてもらいたいものです。

そしてこの記事の意図は、こうしたブラックプロパガンダを多少なりとも防ぐことです。