Last updated: Thu Apr 22 06:34:56 AM CEST 2021
Last year I bought a gaming computer and out of curiosity also installed Ubuntu on it. My main development machine is a MacBook Pro 16-inch, but for old times’ sake I tried to do some programming with the Ubuntu installation.
Now, I used Ubuntu as my main OS from 2004 to 2011, before switching to MacBooks and macOS, which I’ve been using ever since. That is to say I half-expected audio, scroll speed, mouse buttons, and printers to be, ehm, finicky.
What I didn’t expect was this:
Ubuntu feels snappier!
The machines — the MacBook and the gaming computer — have roughly the same specs, so how the same things feel instant on one and, well, laggy in comparison on the other?
What things? Short-lived processes that are not IO bound and not CPU heavy. 90% of my time developing is spent inside tmux inside Kitty; that’s where I start a lot of one-off shells, close them, run a ton of short-running commands, such as git status
. All of this, including typing text into the terminal and into Neovim, feels instant on Ubuntu.
I still don’t know why. My suspicion: processes start faster on Linux and something is making them slower on macOS.
I’m using this page here to document what I find.
macOS | Linux | |
---|---|---|
Model | MacBook Pro (16-inch, 2019) | |
OS | macOS Catalina, Version 10.15.7 | Ubuntu 20.10 |
Processor | 2,4 Ghz 8-Core Intel Core i9 | AMD Ryzen 7 5800X, 8x 3.8GHz, 32MB L3 Cache |
Memory | 64 GB 2667 MHz DDR4 | 64GB DDR4-3000 CL16, Corsair Vengeance LPX black |
Graphics | AMD Radeon Pro 5500M | NVIDIA GeForce RTX 3070, 8GB |
zsh
startup time/usr/bin/time /bin/zsh -i -f -d -c 'for i in $(seq 1 500); do /bin/zsh -c "echo hello >/dev/null && exit 0"; done'
Results:
macOS | Linux | |
---|---|---|
Run #1 | 2.08s | 0.38s |
Run #2 | 2.55s | 0.37s |
Run #3 | 2.15s | 0.44s |
Run #4 | 2.11s | 0.41s |
git status
In sourcegraph/sourcegraph
, with a clean working directory, after running git gc
, on main@62cc96c96d59e8d8beffe3aca9afdc18c4a98619
:
/usr/bin/time /bin/zsh -i -f -d -c 'export GIT_CONFIG_NOSYSTEM=1 && export GIT_CONFIG=/dev/null && for i in $(seq 1 100); do git status >/dev/null; done'
macOS | Linux | |
---|---|---|
Run #1 | 5.38s | 0.64s |
Run #2 | 5.21s | 0.64 |
Run #3 | 5.32s | 0.64 |
Run #4 | 5.29s | 0.53 |
// main.c
int main(int argc, char *argv[]) {
return 0;
}
On Linux: compiled with gcc -o main main.c
and then
/usr/bin/time /bin/zsh -i -f -d -c 'for i in $(seq 1 100); do /home/mrnugget/main; done'
On macOS: compiled with clang -o main main.c
and then
/usr/bin/time /bin/zsh -i -f -d -c 'for i in $(seq 1 100); do /Users/thorstenball/main; done'
Results:
macOS | Linux | |
---|---|---|
Run #1 | 0.24s | 0.02s |
Run #2 | 0.21s | 0.01s |
Run #3 | 0.21s | 0.02s |
Run #4 | 0.21s | 0.02s |
// main.c
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]) {
int num = atoi(argv[1]);
printf("%d\n", num*num);
return 0;
}
On Linux: compiled with gcc -o main main.c
and then
/usr/bin/time /bin/zsh -i -f -d -c 'for i in $(seq 1 500); do /home/mrnugget/main ${i} >/dev/null; done'
On macOS: compiled with clang -o main main.c
and then
/usr/bin/time /bin/zsh -i -f -d -c 'for i in $(seq 1 500); do /Users/thorstenball/main ${i} >/dev/null; done'
Results:
macOS | Linux | |
---|---|---|
Run #1 | 1.20s | 0.12s |
Run #2 | 1.47s | 0.11s |
Run #3 | 1.06s | 0.11s |
Run #4 | 1.03s | 0.10s |