Rust コンパイル最適化：小さく、速く、または両方？

[![表紙](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3967621/4de781c1-213c-4260-969f-5bcecbf1c321.png)](https://leapcell.io/?lc_t=q_rustbuildoptim)

あなたはすでに Rust プロジェクトの開発を完了し、現在はコンパイルに取り組んでいます。では、コンパイルされたファイルをできるだけ小さくするには？最速で動作させるには？あるいは、小さくて速い両方を実現するには？  

以下のような考え方があるでしょう：  

- **ファイルを最小化する**：組み込み開発向け。プロジェクトは大きくなく、複雑でもなく、元々の動作速度は十分速い。ただし、ファイルサイズを極限まで小さくしたい。  
- **ファイルの実行速度を最大化する**：ネットワークサービス向け。プロジェクトのサイズは気にせず、とにかく最大限の並列処理性能を求める。  
- **バランスを取る**：どのようなプロジェクトにも適した最適な中間点を目指す。  

以下の設定を `Cargo.toml` ファイルに追加し、`cargo b --release` を実行するだけで、目的に合った最適なバイナリを生成できます。  

## 設定例  

### 最小の実行ファイルを生成  

```toml
[profile.release]
opt-level = "z"       # コードサイズの最適化
lto = true            # リンク時最適化（Link Time Optimization）の有効化
codegen-units = 1     # コード生成ユニットを減らし、最適化を強化
panic = "abort"       # panic 時に 'unwind' ではなく 'abort' を使用
strip = "debuginfo"   # デバッグ情報を削除
```

### 最速の実行ファイルを生成  

```toml
[profile.release]
opt-level = 3         # 最高レベルの速度最適化
lto = "fat"           # 最大限のリンク時最適化を有効化
codegen-units = 1     # コード生成ユニットを減らし、最適化を強化
panic = "abort"       # panic 時に 'unwind' ではなく 'abort' を使用
```

### サイズと速度のバランスを取る  

```toml
[profile.release]
opt-level = "s"       # サイズと速度のバランスを取る最適化
lto = "fat"           # 最大限のリンク時最適化を有効化
codegen-units = 1     # コード生成ユニットを減らし、最適化を強化
panic = "abort"       # panic 時に 'unwind' ではなく 'abort' を使用
strip = "symbols"     # シンボル情報を削除し、必要なデバッグ情報は保持
```

## 設定の解説  

### opt-level  

**説明**：コンパイラの最適化レベルを指定する。  

**設定可能な値**：  

- `0`：最適化なし、コンパイル速度最速。  
- `1`：コンパイル速度を優先した軽度の最適化。  
- `2`：コンパイル速度と実行速度のバランスを取る（デフォルト）。  
- `3`：最大限の実行速度最適化。  
- `"s"`：コードサイズの最適化。  
- `"z"`：`"s"` よりさらに積極的なサイズ最適化。  

**選択理由**：  
- **最小のバイナリを生成する**ために `"z"` を選択。  
- **最速のバイナリを生成する**ために `3` を選択。  

### lto  

**説明**：リンク時最適化（Link Time Optimization, LTO）を有効にするかどうかを指定する。  

**設定可能な値**：  

- `false`：LTO 無効（デフォルト）。  
- `true`：LTO を有効化。  
- `"thin"`：軽量な LTO を有効化。  
- `"fat"`：最大限の LTO を有効化。  

**選択理由**：  
LTO を有効にすることで、バイナリサイズの縮小と実行時の性能向上が可能。  
- `"thin"` はバランス型。  
- `"fat"` は最大限の最適化を実施（ただしコンパイル時間が増加）。  

### codegen-units  

**説明**：コード生成ユニットの数を制御する。  

**設定可能な値**：  
デフォルトは `16`。`1` に設定すると最適化が最大化される。  

**選択理由**：  
コード生成ユニットを減らすと、コンパイラはグローバル最適化を強化でき、より小さくて速いバイナリを生成可能。  
- `1` に設定すると最適化の恩恵を最大限受けられるが、コンパイル時間が増加する。  

### panic  

**説明**：panic 時の挙動を制御する。  

**設定可能な値**：  

- `"unwind"`：スタック展開（デフォルト）。  
- `"abort"`：即時終了。  

**選択理由**：  
`"abort"` を使用すると、バイナリサイズが小さくなり、特定の状況での性能が向上する（スタック展開情報を保持する必要がなくなるため）。  

### strip  

**説明**：デバッグ情報やシンボル情報を削除する。  

**設定可能な値**：  

- `"none"`：何も削除しない（デフォルト）。  
- `"debuginfo"`：デバッグ情報を削除。  
- `"symbols"`：シンボル情報を削除し、最低限のデバッグ情報は保持。  
- `"all"`：すべてのデバッグ情報とシンボル情報を削除。  

**選択理由**：  
不要なデバッグ情報やシンボル情報を削除することで、バイナリサイズを大幅に削減可能。  

## まとめ  

以上が Rust プロジェクトのコンパイル最適化の手法です。  
あなたはもう習得しましたか？  

---

### [私たちはLeapcell、Rustプロジェクトのホスティングの最適解です。](https://leapcell.io/?lc_t=q_rustbuildoptim)

[![Leapcell](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3967621/dc25cc8e-2f9f-4e58-82fa-08ef833a2fba.png)](https://leapcell.io/?lc_t=q_rustbuildoptim)

[Leapcell](https://leapcell.io/?lc_t=q_rustbuildoptim)は、Webホスティング、非同期タスク、Redis向けの次世代サーバーレスプラットフォームです：

**複数言語サポート**

- Node.js、Python、Go、Rustで開発できます。

**無制限のプロジェクトデプロイ**

- 使用量に応じて料金を支払い、リクエストがなければ料金は発生しません。

**比類のないコスト効率**

- 使用量に応じた支払い、アイドル時間は課金されません。
- 例: $25で6.94Mリクエスト、平均応答時間60ms。

**洗練された開発者体験**

- 直感的なUIで簡単に設定できます。
- 完全自動化されたCI/CDパイプラインとGitOps統合。
- 実行可能なインサイトのためのリアルタイムのメトリクスとログ。

**簡単なスケーラビリティと高パフォーマンス**

- 高い同時実行性を容易に処理するためのオートスケーリング。
- ゼロ運用オーバーヘッド — 構築に集中できます。

[ドキュメントで詳細を確認！](https://docs.leapcell.io/)

[![Try Leapcell](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3967621/4342a0b9-e45d-4055-887a-ae3ee2b67b77.png)](https://leapcell.io/?lc_t=q_rustbuildoptim)

Xでフォローする：[@LeapcellHQ](https://x.com/LeapcellHQ)

---

[ブログでこの記事を読む](https://leapcell.io/blog/rust-release-optimization)