君のRustは20倍遅い

Rustはデフォルトでは本来の力を発揮しない。試しに手頃なベンチマークを3個くらい試したらだいたい20~100倍程度遅かった。

「Rustで ○○ を高速にする方法」が知りたい人は、まず、Rustコンパイラが本来の力を発揮しているか確認したほうがよい。

Cargoの場合

Cargoでは --release をつけると本来の力を発揮してコンパイルする。

$ cargo build --release
$ cargo run --release

rustcを直接実行する場合

$ rustc -C opt-level=3 -C debug_assertions=no

上記のオプションを設定しない理由

逆に、上記のオプションを使わない理由としては、デバッグモードのほうが諸々のチェックが実行されてよいというのが挙げられる。

例えば、整数演算のオーバーフローはデバッグモードでは捕捉される。なお、オーバーフローせずに巡回するような計算をしたい場合は wrapped_add などの専用関数を使うべきである。

より詳しくは

rustcは以下のオプションを受けつける。

  • 最適化オプション
    • -C opt-level=0 最適化しない (デフォルト)
    • -C opt-level=1 少し最適化する
    • -C opt-level=2 最適化する (略記: -O)
    • -C opt-level=3 積極的に最適化する
    • -C opt-level=s プログラムサイズを最適化する (nightlyのみ)
    • -C opt-level=z 積極的にプログラムサイズを最適化する (nightlyのみ)
  • デバッグ情報
    • -C debuginfo=0 デバッグ情報を出力しない (デフォルト)
    • -C debuginfo=1 デバッグ情報として行情報のみ出力する
    • -C debuginfo=2 全てのデバッグ情報を出力する (略記: -g)
  • デバッグアサート
    • -C debug-assertions=yes デバッグアサートを有効にする (デフォルト; yes, y, on のいずれでもOK)
    • -C debug-assertions=no デバッグアサートを無効にする (no, n, off のいずれでもOK)
    • これは cfg(debug_assertions) のオンオフを切り替える。debug_assert! などいくつかのライブラリ関数・マクロはこれに基いて動作が変化する。
  • リンク時最適化
    • -C lto LTO(リンク時最適化)を有効化する (デフォルトは無効)
  • パニック戦略
    • -C panic=unwind パニック時にdropを呼びながらスレッドのスタックフレームを遡る (デフォルト)
    • -C panic=abort パニック時にプログラムを即時終了する

cargoはオプションに基いてプロファイルを1つ選択する。 Cargo.toml からプロファイルの情報を取り出し、上記のオプションを設定する。Cargo.toml のプロファイルのデフォルト設定はcargoのマニュアルページに書いてある