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