2 ms·
tl;dr: Homebrew actually takes several times as long to install packages as Nix does, and uses up way more space despite a less isolated toolchain. Now that I'
by pxc 5y ago
tl;dr: Homebrew actually takes several times as long to install packages as Nix does, and uses up way more space despite a less isolated toolchain.
Now that I'm on my Ubuntu system, I can easily test Nix and Homebrew side-by-side.
To make it fair, I've removed almost everything I have installed with Nix, as well as Homebrew. Interestingly, Homebrew is using ~2x as much disk space, and listing my installed packages (none) with Homebrew takes ~30x as long as with Nix:
~
du -hsxc /nix/store /home/linuxbrew
238M /nix/store
584M /home/linuxbrew
822M total
~
time nix profile list
________________________________________________________
Executed in 19.88 millis fish external
usr time 11.21 millis 174.00 micros 11.04 millis
sys time 11.18 millis 141.00 micros 11.04 millis
~
time sudo -H nix profile list
0 flake:nixpkgs#legacyPackages.x86_64-linux.nixFlakes github:NixOS/nixpkgs/b2f2d04f01b3de3abad0dd9bc48ad7a3ee32bbc6#legacyPackages.x86_64-linux.nixFlakes /nix/store/g4xva7x46h5bqqh811n12dzjc7325x21-nix-2.4pre20210326_dd77f71
1 flake:nixpkgs#legacyPackages.x86_64-linux.starship github:NixOS/nixpkgs/b2f2d04f01b3de3abad0dd9bc48ad7a3ee32bbc6#legacyPackages.x86_64-linux.starship /nix/store/5n36vabqg701l9nji30m1r004zcy4q0w-starship-0.51.0
________________________________________________________
Executed in 29.91 millis fish external
usr time 27.30 millis 380.00 micros 26.92 millis
sys time 4.72 millis 283.00 micros 4.43 millis
~
time brew list
==> Formulae
________________________________________________________
Executed in 881.81 millis fish external
usr time 527.24 millis 411.00 micros 526.83 millis
sys time 173.15 millis 298.00 micros 172.85 millis
Homebrew takes about twice as long to search for packages related to Libreoffice (results omitted to HN won't tell me this post is too long):
~
time nix search nixpkgs libreoffice >/dev/null
________________________________________________________
Executed in 554.37 millis fish external
usr time 537.39 millis 434.00 micros 536.95 millis
sys time 16.44 millis 289.00 micros 16.15 millis
~
time brew search libreoffice >/dev/null
________________________________________________________
Executed in 1.33 secs fish external
usr time 578.16 millis 0.00 micros 578.16 millis
sys time 124.57 millis 367.00 micros 124.20 millis
I had some trouble looking for large packages to install with Homebrew and Nix for comparison. It seems that GUI apps (Libreoffice, Firefox, etc.) tend to be packaged exclusively as casks for Homebrew, which means they don't exist on Linux. So instead, I selected a handful of packages from the Linux formulas list[1] that I figured would pull in a substantive dependency closure. Apparently there's no bottle for Crystal, so it took a very long time to install because it had to compile from source. Prior to that, though, installation crashed because of a ulimits issue when ‘pouring the bottle’ for LLVM:
~
time brew install imagemagick bat feh crystal python mruby
==> Downloading https://ghcr.io/v2/linuxbrew/core/zlib/manifests/1.2.11
######################################################################## 100.0%
==> Downloading https://ghcr.io/v2/linuxbrew/core/zlib/blobs/sha256:6f604280b9e056da163b81cef3076b2e39bbd2b8d3cc8c36d27c19c472c760a4
==> Downloading from https://pkg-containers.githubusercontent.com/ghcr1/blobs/sha256:6f604280b9e056da163b81cef3076b2e39bbd2b8d3cc8c36d27c19c472c760a4?se=20
######################################################################## 100.0%
==> Downloading https://ghcr.io/v2/linuxbrew/core/libpng/manifests/1.6.37
######################################################################## 100.0%
==> Downloading https://ghcr.io/v2/linuxbrew/core/libpng/blobs/sha256:c5d219b27780c730af50693110ed2c79e50200d3595c7e395998fe3950354ec9
==> Downloading from https://pkg-containers.githubusercontent.com/ghcr1/blobs/sha256:c5d219b27780c730af50693110ed2c79e50200d3595c7e395998fe3950354ec9?se=20
######################################################################## 100.0%
==> Downloading https://ghcr.io/v2/linuxbrew/core/bzip2/manifests/1.0.8-1
######################################################################## 100.0%
<snip>
==> Installing crystal dependency: llvm@9
==> Pouring llvm@9--9.0.1_5.x86_64_linux.bottle.tar.gz
Error: Too many open files @ rb_sysopen - /home/linuxbrew/.linuxbrew/Cellar/llvm@9/9.0.1_5/bin/llvm-jitlink
________________________________________________________
Executed in 600.02 secs fish external
usr time 203.24 secs 479.00 micros 203.24 secs
sys time 70.80 secs 313.00 micros 70.80 secs
I decided to re-run the brew install command, but skip Crystal, which only took a few more seconds:
~
time brew install imagemagick bat feh python mruby
<snip>
==> Installing mruby
==> Pouring mruby--3.0.0.x86_64_linux.bottle.tar.gz
/home/linuxbrew/.linuxbrew/Cellar/mruby/3.0.0: 323 files, 14.7MB
________________________________________________________
Executed in 20.18 secs fish external
usr time 9.56 secs 0.00 micros 9.56 secs
sys time 3.06 secs 761.00 micros 3.06 secs
I left Crystal in when I tested Nix, since I knew it would be no problem, and Nix was done in ~36 seconds, meaning Homebrew ~17x the time, skipping one package entirely.
After the two install operations, Homebrew was using several more gigabytes of storage than Nix:
du -hsxc /nix/store /home/linuxbrew
2.0G /nix/store
4.9G /home/linuxbrew
6.8G total
I'll reply to this comment with a ‘warmed-up’ test of installing a single additional package, as well. But it seems pretty clear already that it's misleading at best to characterize Homebrew as faster than Nix.
—
1: https://formulae.brew.sh/formula-linux/ https://formulae.brew.sh/formula-linux/
- pxc 5y agoNow for a single-package ‘warmed up’ test, and some cleanup on both sides to see what the total installed size looks like after autoremoval of orphaned dependencies, build-time dependencies, etc. Installing one package with Homebrew, where the whole dependency closure is bottled, no building from source: ~ time brew install graphicsmagick ==> Downloading https://ghcr.io/v2/linuxbrew/core/libxfixes/manifests/5.0.3 ######################################################################## 100.0% ==> Downloading https://ghcr.io/v2/linuxbrew/core/libxfixes/blobs/sha256:3aaba846570380f7dbf5cf7f93280866318a7730c9c5fd38fd1ad275aec037bd <snip> ==> Pouring freeglut--3.2.1_5.x86_64_linux.bottle.tar.gz /home/linuxbrew/.linuxbrew/Cellar/freeglut/3.2.1_5: 20 files, 1.3MB ==> Installing graphicsmagick dependency: jasper ==> Pouring jasper--2.0.32.x86_64_linux.bottle.tar.gz /home/linuxbrew/.linuxbrew/Cellar/jasper/2.0.32: 40 files, 1.1MB ==> Installing graphicsmagick ==> Pouring graphicsmagick--1.3.36.x86_64_linux.bottle.tar.gz /home/linuxbrew/.linuxbrew/Cellar/graphicsmagick/1.3.36: 497 files, 14.7MB ________________________________________________________ Executed in 362.04 secs fish external usr time 56.32 secs 603.00 micros 56.32 secs sys time 20.00 secs 383.00 micros 20.00 secs Installing the same package with Nix: ~ time nix profile install nixpkgs#graphicsmagick ________________________________________________________ Executed in 11.58 secs fish external usr time 701.80 millis 500.00 micros 701.30 millis sys time 310.06 millis 319.00 micros 309.74 millis So in terms of time, they're not really in the same ballpark. Nix is operating in ‘wait a few seconds’ time, and Homebrew is operating in ‘go make yourself a cup of coffee and come back’ time. And after running `brew cleanup` and `brew autoremove`, then `nix-collect-garbage` and `nix-store --optimize`: ~ du -hsxc /nix/store /home/linuxbrew 1.9G /nix/store 3.9G /home/linuxbrew 5.8G total Listing installed packages now: ~ time brew list ==> Formulae aom fontconfig imagemagick libelf libmpc libx11 libxshmfence mesa-glu python@3.9 xinput bat freeglut imath libev libomp libxau libxslt mpdecimal readline xmlto binutils freetype imlib2 libexif libpciaccess libxcb libxt mpfr rtmpdump xorgproto bison gcc isl libffi libpng libxdamage libxv mruby ruby xz brotli gdbm jasper libgcrypt libpthread-stubs libxdmcp libxvmc ncurses shared-mime-info zlib bzip2 gettext jbig2dec libgpg-error libsm libxext libxxf86vm nghttp2 sqlite zstd c-ares ghostscript jemalloc libheif libssh2 libxfixes libyaml openexr unzip curl giflib jpeg libice libtiff libxi little-cms2 openjpeg util-linux docbook glib krb5 libidn libtool libxinerama llvm openldap wayland docbook-xsl gmp libde265 libidn2 libunistring libxml2 lm-sensors openssl@1.1 wayland-protocols expat gnu-getopt libdrm liblqr libva libxrandr m4 pcre webp feh graphicsmagick libedit libmetalink libvdpau libxrender mesa pkg-config x265 ________________________________________________________ Executed in 580.23 millis fish external usr time 478.15 millis 0.00 micros 478.15 millis sys time 108.59 millis 759.00 micros 107.83 millis ~ time nix profile list 0 flake:nixpkgs#legacyPackages.x86_64-linux.imagemagick github:NixOS/nixpkgs/b2f2d04f01b3de3abad0dd9bc48ad7a3ee32bbc6#legacyPackages.x86_64-linux.imagemagick /nix/store/5ps3bydsjiqgycbzg2cxkwyz50m4rga7-imagemagick-7.0.11-6 1 flake:nixpkgs#legacyPackages.x86_64-linux.bat github:NixOS/nixpkgs/b2f2d04f01b3de3abad0dd9bc48ad7a3ee32bbc6#legacyPackages.x86_64-linux.bat /nix/store/0lyhwrmf3nbadavaq3ixfndhiaw3b86l-bat-0.18.0 2 flake:nixpkgs#legacyPackages.x86_64-linux.feh github:NixOS/nixpkgs/b2f2d04f01b3de3abad0dd9bc48ad7a3ee32bbc6#legacyPackages.x86_64-linux.feh /nix/store/sy0xxs6lbvwhidg5dlj6ckwik2mn3b6l-feh-3.6.3 3 flake:nixpkgs#legacyPackages.x86_64-linux.crystal github:NixOS/nixpkgs/b2f2d04f01b3de3abad0dd9bc48ad7a3ee32bbc6#legacyPackages.x86_64-linux.crystal /nix/store/fbnk8kwbllsn2m60d43y2cfqpwbw5pk4-crystal-1.0.0 4 flake:nixpkgs#legacyPackages.x86_64-linux.python github:NixOS/nixpkgs/b2f2d04f01b3de3abad0dd9bc48ad7a3ee32bbc6#legacyPackages.x86_64-linux.python /nix/store/pp0fp5zds7wqhyx6zqnnxl2aqzf4a51r-python-2.7.18 5 flake:nixpkgs#legacyPackages.x86_64-linux.graphicsmagick github:NixOS/nixpkgs/b2f2d04f01b3de3abad0dd9bc48ad7a3ee32bbc6#legacyPackages.x86_64-linux.graphicsmagick /nix/store/fm7fa16blb4xadsxxagxy0vfmhrjqns0-graphicsmagick-1.3.36 ________________________________________________________ Executed in 25.18 millis fish external usr time 18.24 millis 452.00 micros 17.79 millis sys time 9.17 millis 279.00 micros 8.89 millis Nix's output is a mess, visually, and that'll change in the future. But note that it doesn't bother me with the whole dependency closure, and instead tracks what I actually wanted to install. Finally, a removal test. I'll uninstall everything but graphicsmagick, with both package managers. time brew remove imagemagick bat feh python mruby Error: Refusing to uninstall /home/linuxbrew/.linuxbrew/Cellar/python@3.9/3.9.5 because it is required by freeglut, glib, graphicsmagick, jasper, libheif, liblqr, llvm, mesa, mesa-glu and shared-mime-info, which are currently installed. You can override this and force removal with: brew uninstall --ignore-dependencies imagemagick bat feh python mruby Oops. A second try, since Homebrew put me in dependency hell because it doesn't know the difference between what's installed as a dependency and what I explicitly asked it to install (I thought this functionality was needed to implement `brew autoremove`??). ~ time brew remove --ignore-dependencies imagemagick bat feh python mruby Uninstalling /home/linuxbrew/.linuxbrew/Cellar/imagemagick/7.0.11-13_2... (805 files, 31.4MB) Uninstalling /home/linuxbrew/.linuxbrew/Cellar/bat/0.18.1... (12 files, 5.5MB) Uninstalling /home/linuxbrew/.linuxbrew/Cellar/feh/3.7... (26 files, 716.9KB) Uninstalling /home/linuxbrew/.linuxbrew/Cellar/python@3.9/3.9.5... (2,650 files, 76.9MB) Uninstalling /home/linuxbrew/.linuxbrew/Cellar/mruby/3.0.0... (323 files, 14.7MB) ________________________________________________________ Executed in 1.11 secs fish external usr time 874.06 millis 420.00 micros 873.64 millis sys time 224.91 millis 261.00 micros 224.65 millis ~ time brew autoremove <snip> Uninstalling /home/linuxbrew/.linuxbrew/Cellar/libgpg-error/1.42... (48 files, 1.8MB) ________________________________________________________ Executed in 3.35 secs fish external usr time 2.51 secs 424.00 micros 2.51 secs sys time 0.82 secs 261.00 micros 0.82 secs Nice and fast. :) Now for Nix: ~ time begin nix profile remove '.\*' nix profile install nixpkgs#graphicsmagick end ________________________________________________________ Executed in 2.99 secs fish external usr time 499.04 millis 871.00 micros 498.17 millis sys time 126.67 millis 527.00 micros 126.14 millis Not as fast, because I garbage-collected the evaluation of Nixpkgs itself, so it fetched and re-evaluated that. (Also I did this in a weird way because the UI for the `nix profile` command is incomplete and still kinda clunky.) I also need to clean up with Nix: ~ time nix-collect-garbage -d removing old generations of profile /nix/var/nix/profiles/per-user/pxc/profile removing generation 49 <snip> deleting '/nix/store/znvl3v02hy8ffkhwc6m9z1q5pj8j6ppj-setup-hook.sh' deleting '/nix/store/trash' deleting unused links... note: currently hard linking saves -1.14 MiB 188 store paths deleted, 1574.20 MiB freed ________________________________________________________ Executed in 1.23 secs fish external usr time 14.30 millis 160.00 micros 14.14 millis sys time 10.70 millis 96.00 micros 10.60 millis And after cleanup, the usage: ~ du -hsxc /nix/store /home/linuxbrew 412M /nix/store 3.2G /home/linuxbrew 3.6G total Is there a cleanup command I've missed for Homebrew? Performance considerations aren't really among my main concerns when it comes to package management, so I didn't mention them in my original post about what's ‘wrong’ with Homebrew. But I'd have to add it now.