加速 PHP Composer 執行效率

logo-composer-transparent

早上剛起床就看到 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,會比較慢,等到第二次安裝時,就可以減少一大半時間。