SlideShare a Scribd company logo
composerの遅さを

まじめに考える
第98回PHP勉強会
@Hiraku
自己紹介
• 中野 拓 (@Hiraku)
• 口癖「composerが遅い」

packagistのミラー作った http://packagist.jp
• 2015/12からメルカリで働いています。
今日は
composerの話を
しに来ました
composerの遅さをまじめに考える #phpstudy
composerは遅いのか
composer遅いと言う人々
• 中国、フィリピン、日本、ブラジルあたりに
多いらしい
• issueに文句を書いてる人は大体アジア人
• 北米ではcomposerは速い
俺
俺
composerを速くする活動

やってます
• ミラーサイト http://packagist.jp
• 並列化プラグイン hirak/prestissimo
• https://packagist.org/packages/hirak/
prestissimo
packagistのミラーサイト
hirak/prestissimo 

(並列化プラグイン)
インストールするだけで10倍ぐらい速くなります
どちらもコマンド1行で使える
# (ミラーサイトの有効化)
$ composer config -g repositories.packagist composer http://
packagist.jp
# (並列化プラグインのインストール)
$ composer global require hirak/prestissimo
# フィードバック募集中!!
なぜこれで速くなるのか

を解説します
composerが遅い理由
日本で
サーバーが遠い

…で終わるんだが
あえて別の言い方をしたい
光が遅いから。
composerの遅さをまじめに考える #phpstudy
なぜ”光”の話になるのか
サーバーの場所
• packagist.org ← たぶんフランスにある
• github.com ← たぶんサンフランシスコにある
• 日本からの通信で必ず通るもの

=海底ケーブル

=光ファイバー
約8000km
光は結構遅い
• 真空で約30万km/s
• 光ファイバー中で約20万km/s
• 8000kmで片道最低40msかかる
• (実際は他にも遅延原因があるから

もっと遅い)
「40msって速くね?」
• 物理限界が40msであって、実際は(ry
• これにgithub.comの事情が加わる
• https://api.github.com から

https://codeload.github.com へ

毎回リダイレクトしている
HTTPSの往復
• ゼロからHTTPS通信すると、パケットの往復が4回発
生する
• TCPのハンドシェイクで1往復
• TLSのハンドシェイクで2往復
• HTTP本体で1往復
• 1回リダイレクトすると更に倍
約8000km
を8往復
128,000km
地球3.2周分
https://flic.kr/p/7icRw2
composerはこれを

全zipに対して行っている
それぞれが
地球3.2周分
さすがの光でも
• 片道40msで8回往復すると640ms
• しかも実際は
• 海底ケーブルは最短距離を通ってないし
• 途中には様々なルーターやら何やらを通る
からそこでも遅延がある
実際の遅延時間
curlで雑に測ってみる
# (githubから適当なzipをダウンロードする)
$ curl --head 
--location 
--output prestissimo.zip 
https://github.com/hirak/prestissimo/archive/0.1.4.zip 
--write-out " time_namelookup: %{time_namelookup}n
time_connect: %{time_connect}n time_appconnect: %{time_appconnect}
n time_redirect: %{time_redirect}n time_total: %{time_total}"
...
time_namelookup: 0.013
time_connect: 0.201
time_appconnect: 0.884
time_redirect: 1.270
time_total: 2.400
(試行1回と雑なので、
目安だと思ってください)
項目の意味
time_namelookup

(0.013)
開始からDNS解決まで(秒)
time_connect

(0.201)
開始からTCPハンドシェイク完了まで(秒)
time_appconnect

(0.884)
開始からTLSハンドシェイク完了まで(秒)
time_redirect

(1.270)
リダイレクトで費やした時間(秒)
time_total

(2.400)
かかった時間全て(秒)
フェーズ毎の値に修正
名前解決 0.013
TCPハンドシェイク 0.201 - 0.013 = 0.188
TLSハンドシェイク 0.884 - 0.201 = 0.683
リダイレクト一回分 1.270
HTTPの本体 2.400 - 1.270 - 0.884 = 0.246
2.400秒

中の
0.640秒
が

たぶん光のせい
距離と遅延
• 物理的に通信してるのだから、物理的に距離
が遠いとその分遅れる
• アジアや南米でcomposerが遅いのは、サー
バーから物理的に遠いから
composerを速くする方法
解決方法
1. packagistやgithubが近くにあればいい
2. 往復を減らせばいい
3. 並列化して待ち時間を活用すればいい
4. 光がもっと速くなればいい←難しそう
1. 距離を縮める
• 近くにミラーサイトを建てる
• CDNが導入されてれば同じ効果がある

(packagist本家が導入してくれれば…)
• githubのミラーはちょっと大変…
packagistに関しては
packagist.jpミラーで

実装済み
2. 往復を減らす(1)
• zipあたり8往復するのは無駄
• api.github.com→codeload.github.com

リダイレクトをやめる

最初からcodeloadに取りに行く
• これでzipあたり4往復減らせる
さっきの例で、

1zipダウンロード時間の内訳
download
0.240
redirect
1.270
tls
0.683
tcp
0.188
dns
0.013
リダイレクトを削る
download
0.240
redirect
1.270
tls
0.683
tcp
0.188
dns
0.013
2. 往復を減らす(2)
• 同じコネクションを使いまわして次のzipをダ
ウンロードする(Keep-Alive)
• 初回は省略できないが、2回目以降TLSハンド
シェイクまで省略できる(3往復)
Keep-Aliveで2回目以降省略
download
0.240
redirect
1.270
tls
0.683
tcp
0.188
dns
0.013
zip50個の場合

50 * 4 + 49 * 3 = 347
往復の削減効果
地球69.4周分
節約
https://flic.kr/p/7icRw2
PHPでKeep-Aliveなリクエスト
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'http://example.com/1.txt');
curl_exec($ch);
// 同じ$chを使い回して2回目
curl_setopt($ch, CURLOPT_URL, 'http://example.com/2.txt');
curl_exec($ch);
curl_close($ch);
3. 並列化
• 待ち時間に別のダウンロードを行う
• 通信路の暇をなくせる
• 帯域を100%使いきったら、

並列化の効果は薄い (prestissimoは6並列にした)
• PHPの場合、curl_multiを使えばできる
リダイレクト削減と

Keep-Aliveと

並列化は
hirak/prestissimoで

実装済み
解決方法の現状
packagistが近くにあれば packagist.jpで実装した
リダイレクトを減らす hirak/prestissimoで実装した
Keep-Aliveを使う hirak/prestissimoで実装した
並列化する hirak/prestissimoで実装した
光が速くなれば 未解決
インパクトのある部分は

結構つぶせた
まとめ
本当は
• composerじゃなくて

光がクソ遅いのが全て悪い!と

言いたかったが…
• 光の伝搬時間は全体の一部でしかない。

まだ我々には改善できることがある
我々が知るべきこと
• 地球規模だと光の遅さが体感できる
• 物理限界を意識して実装しよう
• composerの実装・file_get_contents()は

HTTP/1.0で、連続ダウンロードに向いていな
い (curl使おうぜ)
もっと詳しく知りたい人は
←この本にだいたい

書いてあります
光の遅さに文句が言える

エンジニアになろう
ご静聴ありがとうございました
We are hiring!

More Related Content

composerの遅さをまじめに考える #phpstudy