sccacheを使ってRustのビルドを高速化する

Rust実装されたccacheライクなツール[sccache](https://github.com/mozilla/sccache)が[実験的にRustをサポートした](https://github.com/mozilla/sccache/blob/master/docs/Rust.md)とのことで、早速試してみました。

環境はMacOSX10.11.6、rustc-1.19.0-nightly前提です。


## インストール

```shell-session
$ cargo install --force --git https://github.com/mozilla/sccache
```

```shell-session
$ sccache --show-stats
Compile requests                 0
Compile requests executed        0
Cache hits                       0
Cache misses                     0
Cache timeouts                   0
Cache read errors                0
Forced recaches                  0
Cache write errors               0
Compilation failures             0
Cache errors                     0
Non-cacheable compilations       0
Non-cacheable calls              0
Non-compilation calls            0
Unsupported compiler calls       0
Average cache write          0.000 s
Average cache read miss      0.000 s
Average cache read hit       0.000 s
Cache location             Local disk: "/YOUR/HOME/Library/Caches/sccache"
Cache size                      20 MiB
Max cache size                  10 GiB
```

## ビルドしてみる
woothee-rustを使ってビルドを試してみます。
Rust1.18からサポートされた`RUSTC_WRAPPER`を使って`sccache`でビルドします。

### sccache未使用時
```
$ cargo clean; time cargo build
cargo build  17.59s user 1.86s system 120% cpu 16.080 total
```

`cargo clean`するともちろん同じくらいのビルド時間になります。

```
$ cargo clean; time cargo build
cargo build  17.74s user 1.98s system 122% cpu 16.140 total
```

### sccache使用時

```shell-session
$ cargo clean; time RUSTC_WRAPPER=`which sccache` cargo build
RUSTC_WRAPPER=`which sccache` cargo build  0.46s user 0.34s system 4% cpu 18.186 total
$ sccache --show-stats
Compile requests                14
Compile requests executed       12
Cache hits                       0
Cache misses                    12
Cache timeouts                   0
Cache read errors                0
Forced recaches                  0
Cache write errors               0
Compilation failures             0
Cache errors                    12
Non-cacheable compilations       0
Non-cacheable calls              2
Non-compilation calls            0
Unsupported compiler calls       0
Average cache write          0.001 s
Average cache read miss      1.556 s
Average cache read hit       0.000 s
Cache location             Local disk: "/YOUR/HOME/Library/Caches/sccache"
Cache size                      20 MiB
Max cache size                  10 GiB
```

キャッシュされてるので、速くなるはず。

```
$ cargo clean; time RUSTC_WRAPPER=`which sccache` cargo build
RUSTC_WRAPPER=`which sccache` cargo build  0.48s user 0.33s system 36% cpu 2.237 total
$ sccache --show-stats
Compile requests                28
Compile requests executed       24
Cache hits                      12
Cache misses                    12
Cache timeouts                   0
Cache read errors                0
Forced recaches                  0
Cache write errors               0
Compilation failures             0
Cache errors                    12
Non-cacheable compilations       0
Non-cacheable calls              4
Non-compilation calls            0
Unsupported compiler calls       0
Average cache write          0.001 s
Average cache read miss      1.556 s
Average cache read hit       0.000 s
Cache location             Local disk: "/YOUR/HOME/Library/Caches/sccache"
Cache size                      20 MiB
Max cache size                  10 GiB
```

速くなりました。`sccache --show-stats`でキャッシュ使用状況を確認してみると、キャッシュヒットしています。

## バックエンドをRedisにする
sccacheはS3とRedisをバックエンドにすることも可能です。
Redisをバックエンドにしたい場合はsccacheのビルド時に`--features=all`をつけておく必要があります。
（私は試してはいませんが、S3はデフォルトでサポートされているので、環境変数`SCCACHE_BUCKET`を適切に設定すると使用することができるはずです。）

```shell-session
$ cargo install --force --git https://github.com/mozilla/sccache --features=all
```

Redisをバックエンドに使用する場合は、環境変数`SCCACHE_REDIS`にRedisのURLを指定します。

```shell-session
$ export SCCACHE_REDIS=redis://localhost:6379/
$ RUSTC_WRAPPER=`which sccache` cargo build
```

## その他
もちろん`ccache`と同じようにgccやclangを使ったCやC++のコンパイルにも使用することができます。ただし、`ccache`でいうところの[ダイレクトモード](https://ccache.samba.org/manual.html#_the_direct_mode)を`sccache`が現状サポートしておらず、キャッシュキーを生成する際にプリプロセスが走るため、`ccache`よりも時間がかかります。