RustCompileTimesAreNotSlow
I’m sick of the myth that Rust compile times are slow. I maintain that there are far slower tools out there that people don’t bitch about half as much. Let’s look at some case studies.
nalgebra
Written in Rust. Big and hairy and complicated and gives the compiler a good damn workout in terms of metaprogramming.
nalgebra > tokei
-------------------------------------------------------------------------------
Language Files Lines Code Comments Blanks
-------------------------------------------------------------------------------
Makefile 2 23 16 1 6
Markdown 4 501 501 0 0
Rust 196 37179 27507 4481 5191
Shell 2 40 34 2 4
Plain Text 1 21 21 0 0
TOML 3 99 83 2 14
-------------------------------------------------------------------------------
Total 208 37863 28162 4486 5215
-------------------------------------------------------------------------------
nalgebra > cargo check
Compiling num-traits v0.2.4
Compiling typenum v1.10.0
Compiling num-complex v0.2.0
Compiling matrixmultiply v0.1.14
Checking rawpointer v0.1.0
Checking rand_core v0.2.1
Checking libc v0.2.42
Checking rand v0.5.1
Checking generic-array v0.11.0
Checking approx v0.2.0
Checking alga v0.6.0
Checking nalgebra v0.15.1 (file:///home/icefox/tmp/nalgebra)
Finished dev [unoptimized + debuginfo] target(s) in 30.45s
nalgebra > touch src/**.rs
nalgebra > cargo check
Checking nalgebra v0.15.1 (file:///home/icefox/tmp/nalgebra)
Finished dev [unoptimized + debuginfo] target(s) in 3.89s
This is what actually matters. The time between making a change and knowing if you fucked it up. You can use cargo watch
to get a head start on it too.
Let’s run clippy on it and see how long it takes. This is what actually matters: time to check and give compilation errors and time to lint.
nalgebra > touch src/**.rs
nalgebra > time cargo +nightly clippy
...ten jillion lints later...
27.44user 0.27system 0:27.76elapsed 99%CPU (0avgtext+0avgdata 430472maxresident)k
Ok, now let’s build the damn thing:
nalgebra > rm target
nalgebra > cargo build --release> cargo build --release
Compiling num-traits v0.2.4
Compiling num-complex v0.2.0
Compiling typenum v1.10.0
Compiling matrixmultiply v0.1.14
Compiling libc v0.2.42
Compiling rand_core v0.2.1
Compiling rawpointer v0.1.0
Compiling rand v0.5.1
Compiling generic-array v0.11.0
Compiling approx v0.2.0
Compiling alga v0.6.0
Compiling nalgebra v0.15.1 (file:///home/icefox/tmp/nalgebra)
Finished release [optimized] target(s) in 28.39s
But that’s not fair ’cause it’s building dependencies, let’s try just nalgebra.
nalgebra > touch src/**.rs
nalgebra > cargo build --release
Compiling nalgebra v0.15.1 (file:///home/icefox/tmp/nalgebra)
Finished release [optimized] target(s) in 22.21s
Work project
This is a typescript web frontend project for work that I can’t talk too much about. But I can give stats.
work_project > tokei
-------------------------------------------------------------------------------
Language Files Lines Code Comments Blanks
-------------------------------------------------------------------------------
Dockerfile 1 29 19 6 4
HTML 1 27 24 1 2
JavaScript 9 468 412 28 28
JSON 6 12437 12437 0 0
Makefile 1 48 37 2 9
Markdown 2 87 87 0 0
Sass 30 864 705 44 115
Shell 6 47 28 8 11
SVG 3 124 121 3 0
Plain Text 1 4 4 0 0
TypeScript 490 52821 42662 6263 3896
YAML 15 1194 1135 16 43
-------------------------------------------------------------------------------
Total 565 68150 57671 6371 4108
-------------------------------------------------------------------------------
So about 2x the size of nalgebra. That’s fine, it’s in the right order of magnitude. How long does it take to lint?
work_project > time make lint
npm run lint:src
> tslint --format stylish --type-check --project tsconfig.json
npm run lint:style
> stylelint --allow-empty-input src/**/*.scss
55.19user 0.66system 0:39.77elapsed 140%CPU (0avgtext+0avgdata 584488maxresident)k
16inputs+16outputs (0major+178549minor)pagefaults 0swaps
So about the same in terms of time per line of code, and it doesn’t catch one damn tenth of what clippy does.
Actually running
> make start
make start
./scripts/start.sh
> lidarmill@0.0.0 start /home/icefox/work/phoenix/lidarmill-frontend
> webpack-dev-server --colors --progress
10% building modules 1/1 modules 0 active
Project is running at http://0.0.0.0:35400/
webpack output is served from /dist
404s will fallback to /index.html
10% building modules 4/5 modules 1 active ...enix/lidarmill-frontend/src/index.tsx
[at-loader] Using typescript@2.2.0 from typescript and "tsconfig.json" from /home/icefox/work/phoenix/lidarmill-frontend/tsconfig.json.
94% asset optimization
[at-loader] Checking started in a separate process...
[at-loader] Ok, 0.499 sec.
Hash: 2e4843942db5ad9b4612
Version: webpack 2.6.1
Time: 22827ms
Asset Size Chunks Chunk Names
bundle.js 8.94 MB 0 [emitted] [big] main
main.css 23.9 kB 0 [emitted] main
bundle.js.map 10.8 MB 0 [emitted] main
main.css.map 27.1 kB 0 [emitted] main
...
So, 22.8 seconds. This isn’t entirely fair either ’cause it mongles all dependencies, which include:
$ tokei node_modules/
-------------------------------------------------------------------------------
Language Files Lines Code Comments Blanks
-------------------------------------------------------------------------------
Autoconf 2 392 229 128 35
BASH 1 23 19 2 2
Batch 1 190 166 1 23
CoffeeScript 36 3856 3035 227 594
CSS 178 11196 8581 743 1872
Handlebars 2 61 50 3 8
HTML 109 22765 19875 58 2832
JavaScript 12824 1767414 1354510 218916 193988
JSON 2093 269496 269496 0 0
JSX 11 10630 9170 322 1138
Makefile 48 1144 775 119 250
Markdown 1842 216121 216121 0 0
Module-Definition 5 525 437 0 88
Python 4 731 418 158 155
ReStructuredText 27 3974 3974 0 0
Sass 4 101 86 0 15
Shell 18 1236 887 168 181
SVG 2 14 13 1 0
Plain Text 52 2114 2114 0 0
TypeScript 321 121788 79151 31264 11373
XML 2 2192 1948 11 233
YAML 14 222 157 30 35
-------------------------------------------------------------------------------
Total 17596 2436185 1971212 252151 212822
-------------------------------------------------------------------------------
okay they’re kinda slow
need more data