23.7K Views
March 21, 22
スライド概要
88IO氏( https://twitter.com/88IOBF )によるスライドです。本人に許可をとって掲載しています。
↓このイベントで発表されました。
【LT】第5回バーチャル学生LT&にこのこLT会_4 in バーチャル名工大 - connpass
https://student-lt.connpass.com/event/240230/
Rustのバイナリサイズ削減 88IO
自己紹介 • 名前: 88IO ("はやと"の語呂合わせ派生) • 名工 情報工 3年 • 一応進級できそう • 来年度B3は情報ネットワークで会うかも(再履修) • C0de OB • 技術系:特になし、ThinkPad好き • 趣味 :映画、カメラ
経緯 • Rust入門中 • ツイート用Discord BotをRustで書き直した • Raspberry Piで稼働 • 想像以上にバイナリサイズが大きい
ツイート用Discord Bot
ツイート用Discord Bot • リポジトリ • https://github.com/88IO/blogpost-rs • 外部クレート serenity Discord API ラッパー tokio 非同期処理 regex 正規表現 dotenv .envファイル読み込み egg-mode Twitter API ラッパー
実行条件 • 対象 • x86_64-unknown-linux-gnu • Rust version 1.60.0 nightly • CPU:AMD Ryzen™ 7 2700X • RustのビルドシステムCargoを使用 • バイナリサイズ削減のオプションはCargo.tomlに記述する
バイナリサイズ削減 • 参考 • Minimizing Rust Binary Size - RustRepo • https://rustrepo.com/repo/johnthagen-min-sized-rust • Rustのバイナリサイズを削減する - Qiita • https://qiita.com/hhatto/items/75d12de5a39ee37c5ddb • The Cargo Book • https://doc.rust-lang.org/cargo/index.html
リリースビルドのバイナリサイズ ビルド バイナリサイズ debug 179.5 MiB release 18.8 MiB - 160.7 MiB
1.シンボル・デバッグ情報の削除 • 対象 • Unix / Linux • Rust version >= 1.59 • 方法 • stripコマンド または Cargoのstripオプションを使用
1.シンボル・デバッグ情報の削除 [profile.release] strip = true String value Boolean value "symbols" true "debuginfo" "none" false
1.シンボル・デバッグ情報の削除 stripオプション バイナリサイズ false (default) 18.8 MiB true 11.3 MiB - 7.5 MiB
2.サイズ最適化 • 対象 • Rust version >= 1.28 • 方法 • 最適化レベルを "s" または "z" に指定 [profile.release] opt-level = "z"
2.サイズ最適化 opt-level 0 no optimizations (debug) 1 basic optimizations 2 some optimizations 3 All optimizations (release) "s" optimize for binary size "z" optimize for binary size, but also turn off loop vectorization.
2.サイズ最適化 opt-level バイナリサイズ 3 (default) 18.8 MiB "s" 18.4 MiB "z" 19.9 MiB - 0.4 MiB
3.LTO (Link Time Optimization)有効化 • 対象 • Rust version >= 1.0 • 方法 • Cargoのltoオプションを使用 [profile.release] lto = true
3.LTO有効化 lto バイナリサイズ false (default) 18.8 MiB true 13.0 MiB - 5.8 MiB
4.並列コード生成ユニットの削減 コンパイル時間を犠牲に一部の最適化を可能にする • 方法 • Cargoのcodegen-unitsを1つに減らす [profile.release] codegen-units = 1
4.並列コード生成ユニットの削減 Codegen-units バイナリサイズ 16 (default) 18.8 MiB 1 15.9 MiB - 2.9 MiB
5.パニック時の強制終了 パニック時にバックトレースを生成しないことで該当コードを 削減する • 方法 • Panicオプションを"abort"に指定する [profile.release] panic = "abort"
5.パニック時の強制終了 オプション指定 バイナリサイズ "unwind" (default) 18.8 MiB "abort" 16.2 MiB - 2.6 MiB
オプションまとめ 以下のビルドオプションをCargo.tomlに記述する 1.シンボル情報の削除 2.サイズ最適化 3.LTO有効化 4.並列コード生成ユニット数削減 5.パニック時の強制終了 [profile.release] strip = true opt-level = "s" lto = true codegen-units = 1 panic = "abort"
オプションまとめ デフォルトとの差分 Default [profile.release] strip = 'none' opt-level = 3 lto = false codegen-units = 16 panic = 'unwind' 変更後 [profile.release] strip = true opt-level = "s" lto = true codegen-units = 1 panic = "abort"
削減結果 オプション指定 バイナリサイズ なし 18.8 MiB あり 6.2 MiB - 12.6 MiB