PSR標準を使用してファイルを検索するか、composer=クラスをスキャンするディレクトリを指定します。The )ドキュメントでは、PSR-4 標準の使用を推奨しています。最適化された を作成するためのcomposerのオプションもあります基本的に完全なクラスマップを生成するオートローダー では、クラスマップを使用するのが最適な方法である場合、PSR-4を使用する必要があるのはなぜですか?
とにかく整理するのに良い方法なので、ディレクトリ構造を保持するのは理にかなっています。ただし、論理的なオプションとしては、開発マシンでPSR-4ロードを使用し、実稼働環境のクラスマップを使用することが考えられます。そうすれば、新しいクラスを作成するたびにクラスマップを再構築する必要はありませんが、実稼働環境では、次の呼び出しを行わずに展開プロセスの一部として完全なクラスマップを作成します
./composer.phar dump-autoload -o
クラスマップが実際に速い場合、composerでPSR-0またはPSR-4オートロードを使用する理由は何ですか?
より実用的だからです。
プロダクションでは、新しいクラスを追加しないため、クラスマップ(composer dumpautoload -o
)を使用できますが、開発環境ではPSR-0またはPSR-4によって提供される柔軟性(つまり、何もしない)新しいクラスを追加する場合)。
更新:composer install -o
を使用することもでき、より簡単です。
問題は、クラスマップが実際にすべてのケースで高速ではないということです!
クラスマップの速度は、常に必要なロード、解析(オペコードキャッシュがここで役立ちます)してから実行する前に、ファイルが存在する場合にファイルシステムをチェックする必要がないためです。
ただし、クラスマップの欠点は、実際に運用コードで使用せずに、使用するライブラリに含まれるすべてのクラス、インターフェイス、および特性に対して大量のデータを生成する可能性があることです。巨大な配列をロードするのは無料ではありません-コードを何度も解析する必要はありませんが(opcodeキャッシュ)、実行する必要があり、配列データ構造をメモリに配置し、多くの文字列で満たしてから、他の何かに使用できたかもしれないメモリの一部を使い果たします。
このトピックについて議論している2つのリソースが見つかりました。まず、 github issue#1529 composerスキャンの必要を避けるためにシンボリックリンクを使用するオートローダーのさらなる改善を提案しています。複数のディレクトリ。
また、そこでの議論は、PSR-0自動ロード宣言で可能な限り最良の名前空間プレフィックスまたはクラス名プレフィックス、つまり可能な限り長いものを実際に使用しようとする必要があることを明らかにしています。宣言で複数のプレフィックスを使用することもできます。
次に、 その問題にリンクされているブログ投稿 があります。これは、ストックEZPublish 5を使用し、APCキャッシングやクラスマップダンプを含む設定をいじるxhprofベンチマークを文書化します。
お金の引用:
このコマンドは、インデックスとしてのクラス名と値としてのクラス定義を含むファイルへのパスで構成されるハッシュである配列を含む662KiB vendor/composer/autoload_classmap.phpファイルを作成しました。この投稿を書いている時点では、この配列は4168エントリで構成されています。 [...]最も効率的な自動読み込みメカニズムを提供しますが、実際には速度が低下します(254.53リクエスト/秒から197.95まで)。その理由は、ファイルがAPCによってキャッシュされたとしても、4100を超えるエントリを持つマップを含むPHP配列は、すべてのリクエストで再作成する必要があるためです。
クラスマップは高速になりますか?もちろん。すべてのケースで最速ですか?もちろんそうではありません-リクエストごとに使用されるクラスと未使用のクラスに依存します。そのため、アプリケーションが実際にマップですべてのクラスを実際に使用している場合でも、リクエストごとにクラスの約10%しか使用しない場合、クラスマップはさらに遅くなる可能性があり、使用するライブラリの自動ロード宣言を最適化する方が良いでしょう。実際、すべてのクラス名のプレフィックスは、必ず1つのディレクトリのみを指す必要があります。
達成できるパフォーマンスの向上は、リクエストあたり約1桁のミリ秒程度の領域であることに注意してください。その数値が5〜10%の範囲で大幅なパフォーマンスの向上をもたらす場合、アプリケーションは確かに素晴らしいです。しかし、実際にそのパフォーマンスの範囲内にいる場合、クラスマップが常に高速であると盲目的に信じることは、おそらく多くの不要なCPUサイクルを浪費します。
何かを最適化する場合:測定します!測定できない場合、実際に改善されるかどうかをどのように知るでしょうか?
クラスを追加/変更した場合に必要なことは次のとおりです。
したがって、基本的には、新しく作成したクラスがオートローダー内に正しく存在するかどうかを心配することなく、psr-4とpsr-0を使用することができます。さらに、名前空間を表すfreeライブラリの適切なディレクトリ構造を取得します。
オートローダーファイル:
ここでの重要な議論は、composer.jsonでpsr-4またはpsr-0を使用することですforces厳密な標準に従ってクラスファイルを整理することです。これにより、composer.jsonを見る他の人(または2年後の自分)がクラスがどこにあるかをすぐに知ることができます。
これを間違えた場合、例えば名前空間のスペルを間違えた場合、「クラスが見つからない」ために、開発中またはユニットテストで検出される可能性があります。これを修正する必要があるため、これは良いことです。
クラスマップははるかに寛容であり、クラスファイルの任意の編成を可能にし、読者を暗闇の中に残します。
そのため、他の人がすでに述べたように、composer.jsonでpsr-4またはpsr-0を使用し、開発中にそれを操作してから、本番用の-oオプションを検討します。しかし、これが実際にパフォーマンス上の利点をもたらすかどうかを測定してください!
PSR-0およびPSR-4(およびクラスマップ)の実装の問題は、最適化を考慮していません。実装はせいぜい欠けています。
ただし、クラスマップの背後にある考え方は機能します。
クラスマップを生成するライブラリを作成しました。ただし、このクラスマップははるかに単純ですが、最適化されています。
https://github.com/eftec/autoloadone
大きなプロジェクトでもマップは縮小され、同じフォルダーに含まれている場合、同じ名前空間の同じクラスがグループ化されます。そうでなければ、それらも含まれている問題ではありません。また、クラスに名前空間がない場合、ファイル内に2つのクラスがある場合、ファイルはスコープ外にありますが、問題ではなく、すべてを追跡します。一部のフォルダーまたは名前空間を除外することもできます。
たとえば、大きなプロジェクトで
Number of Classes: 898
Number of Namespaces: 62
Number of Maps: 117
Number of PHP Files: 1693
Number of PHP Autorun: 0
Number of conflict: 1
Ratio map: 6.91% (less is better. 100% means one map/one file)
Map size: 12.9 kbytes (less is better, it's an estimate of the memory used by the map)
したがって、898クラスのプロジェクトでは、マップは12.9kbのみを使用します。
そして、パフォーマンスの違いは何ですか:
Composerの自動ロードには、(呼び出しごとに)次のファイルが含まれます。
または、ファイルを実行します:
Opcacheは驚異的ですが、(1つではなく)少なくとも2つのインクルードが含まれていますが、1つは巨大であり、依然としてオーバーヘッドであり、呼び出しごとです。
だから、これは高速です。プロジェクトによって異なりますが、通常はPSR-0の方が速いことを確認しました。ただし、違いはわずかで、どちらも遅いです。 :-P