Rust には、次の 3 つの種類のいずれかで使用できる「インライン」属性があります。
#[inline]
#[inline(always)]
#[inline(never)]
いつ使用すればよいですか?
Rustのリファレンスでは、インライン属性セクション言う
コンパイラは、内部ヒューリスティックに基づいて関数を自動的にインライン化します。関数を誤ってインライン化すると、実際にプログラムが遅くなる可能性があるため、注意して使用する必要があります。
Rust内部フォーラムでは、huonもインライン指定については保守的。
しかし、私たちはかなりの使用標準ライブラリを含む Rust ソース内。1 行関数には多くのインライン属性が追加されており、参照によると、コンパイラは簡単に見つけてヒューリスティックを通じて最適化できるはずです。これらは実際には必要ではないのでしょうか?
ベストアンサー1
現在の Rust コンパイラの制限の 1 つは、LTO (リンク時最適化) を使用していない場合、マークされていない関数を#[inline]
クレート間でインライン化しないことです。Rust は、LLVM の LTO 実装が大規模なプロジェクトにうまく対応できないため、C++ に似た別のコンパイル モデルを使用します。したがって、他のクレートに公開される小さな関数は手動でマークする必要があります。これはあまり良い状況ではありませんが、将来的には LTO と MIR インライン化の改善の組み合わせによって修正される可能性があります。
#[inline(never)]
デバッグに役立つことがあります (期待どおりに動作しないコードの一部を分離する)。理論的には、ベンチマークに使用できますが、通常は良い考えではありません。インライン化をオフにしても、定数の伝播などの他のプロシージャ間の最適化は妨げられません。通常のコードでは、エラー処理にのみ使用される頻繁に使用されるヘルパー関数がある場合、コードサイズを削減できます。
#[inline(always)]
一般的には、これは悪い考えです。関数が十分に大きく、コンパイラがデフォルトでインライン化しない場合は、呼び出しのオーバーヘッドが問題にならないほど大きいということです (過度のインライン化は命令キャッシュの負荷を増加させます)。例外もありますが、それを正当化するにはパフォーマンス測定が必要です。この例検討する価値があるような状況です。コードの品質#[inline(always)]
を向上させるためにも使用できます-O0
が、通常は心配する必要はありません。