早上剛起床就看到 DK 發表一篇增加一行程式碼讓 PHP Composer 效率爆增,Composer 是 PHP 套件管理工具,現在各大 Framework 都用 Composer 管理套件相依性,但是最讓人擔憂的是,每次執行 composer install
或 update 的時候,機器就會開始哀號,然後等了很久指令才執行完成。今天看到 Github 上 Composer 為了改善執行效率及時間就把 gc disabled。這 commit 引發了很多人迴響,超多搞笑留言圖片。底下有兩種方式可以加速 Composer 執行效率
更新 Composer 到最新版
請透過 composer self-update
將 composer 更新到最新版,因為今天已經將 gc_disable
納入官方程式碼內了。
/** * Run installation (or update) * * @return int 0 on success or a positive error code on failure * * @throws \Exception */ public function run() { gc_disable();
測試數據如下,原本
$ composer update --dry-run --profile # Memory usage: 164.29MB (peak: 393.37MB), time: 82.9s
關閉 gc 後
# Memory usage: 163.99MB (peak: 318.46MB), time: 47.14s
如果尚未更新 composer 到最新版,可以透過底下指令:
$ php -d zend.enable_gc=0 composer update --dry-run --profile
其實真正原因是出在 GC,可以參考此留言
This might indeed be a GC issue. If there are many objects created – all of which cannot be cleaned-up. PHP’s GC will kick in frequently trying to clean-up, only to discover that it cannot clean-up anything, and just wastes time/CPU cycles. This might be the reason why you see the effect for big projects (= many objects), but not so much for small projects (= GC is not kicking in frequently). In these cases, disabling GC entirely is a lot faster (at the cost of some more memory consumption ofc). If no-one has checked yet, it might be worth to add gc_disable() to the update/install command.
保留 composer.lock
在還沒有關閉 GC (Garbage Collection) 之前,可以透過 cache 來減少 composer 執行時間,Laravel 本來將 composer.lock
放入 .gitignore
內,現在我們將此行拿掉,也就是不要任意升級版本,避免讓程式 crash 掉。並且透過底下指令來初始化專案,保留 composer.lock
有兩個好處
- 不會因為
composer update
讓整個專案爛掉 - Deploy 時
composer install
會直接從本地端抓取相依程式碼
底下為 Deploy 上 Production 時所執行的指令
$ composer install --prefer-dist --no-dev --no-scripts
第一次由於沒有 cache,會比較慢,等到第二次安裝時,就可以減少一大半時間。