- 2014-12-04 (木) 13:17
- PHP
まだ 12 月早々ですが、PHP ユーザに素敵なクリスマスプレゼントが届きました。
いまや使うのが当たり前となった Composer ですが、複雑な依存解決に実行時間がかかるのがネックでした。
これは日本国内だけでなく、海外のユーザも同じで、皆がしょうがないと思いつつも、小さな不満を持ちながら使っていました。
そんな、ある日、わずか 1 行のコードが追加されたことで、実行時間が、わずか半分になるという現象が起こりました。
Composer を倍速にするには?
composer self-update
を実行して、最新版にするだけです。
$ composer self-update
実際の効果
このコードの効果を見てみましょう。composer コマンドの --profile
オプションを使って、実行時間と使用メモリ量を出力します。
$ composer update --dry-run --profile
まずは、比較のために、変更される前の composer で実行します。3 回続けて実行した結果が以下です。
# composer = 1.0.0-alpha8 Memory usage: 199.44MB (peak: 854.47MB), time: 397.92s Memory usage: 199.44MB (peak: 854.68MB), time: 353.29s Memory usage: 200.05MB (peak: 855.5MB), time: 338.84s
続いて、変更後の composer で実行します。
# composer = 1.0-dev (37ec0bde9dd6826591308e7a1ad55cb5e38ef117) Memory usage: 122.17MB (peak: 209.3MB), time: 67.82s Memory usage: 122.17MB (peak: 209.29MB), time: 16.34s Memory usage: 122.17MB (peak: 209.3MB), time: 16.77s
なんと、メモリピークは 1/4 、そして実行時間は、6-20 倍ほど早くなっています!!
Github のコメントなどで見ると、効果のほどは、定義されている依存関係や環境によっても異なり、メモリ使用量の変化は小さい場合もあるようですが、実行時間に関しては概ね半分程度にはなるようです。
たった 1 行のコード
では、どんな魔法を使って、この改善を行ったのでしょうか。
その答えが、下記の commit です。
https://github.com/composer/composer/commit/ac676f47f7bbc619678a29deae097b6b0710b799
変更したコードは、わずか 1 行です。(実際には、空行の追加があるので、2 行)
public function run() { + gc_disable();
これは、PHP 5.3 にて、循環参照によるメモリ・リークを解消するために導入されたガベージコレクションを無効にする関数です。デフォルトでは有効になっているのですが、今回は、これを無効にしたことで、パフォーマンスが大幅に改善されました。
このガベージコレクションについては、PHP マニュアルに記述があります。
http://php.net/manual/ja/features.gc.php
また、今回の事象を踏まえて、さらに詳細な内容がまとまっていますので、こちらもどうぞ。
ircmaxell’s blog: What About Garbage?
PHP ユーザの熱狂
この、あまりの効果に PHP ユーザが熱狂しました。Twitter でも多くのコメントがありますが、最も分かりやすいのが、Github です。
この修正を行った commit のページには、数多くの賞賛コメントが付いており、祭りの様相を呈しています:D
Gif アニメーションが多数貼られており、ブラウザで開き切るのも時間がかかる状況です。もはや、悪ノリ感もありますが、いかに多くの PHP ユーザがこの改善を喜んでいるかが分かりますね。
https://github.com/composer/composer/commit/ac676f47f7bbc619678a29deae097b6b0710b799
さいごに
わずか、1 行のコードで、問題が大幅に改善される。
特にパフォーマンスの問題に関しては、こうした体験をした人は多いのではないでしょうか。その 1 行が生まれるまでには、多くの時間が必要なのです。Github 上でもディスカッションが行われていました。
そして、結果として書いたコードは、たったの 1 行でした。
早くなった composer を動かしつつ、やはり大事なのはコードを書いた量ではなく、問題を解決することなんだな、としみじみ感じた出来事でした。
なお、速くなるのは、依存解決の部分なので、ダウンロードの時間は変わりません。あしからず。