[解決済み】インライン関数を使用する場合と使用しない場合とは?
質問
インラインはコンパイラへのヒントまたはリクエストであり、関数呼び出しのオーバーヘッドを回避するために使用されることは知っています。
では、ある関数がインライン化の候補であるかどうかは、何を基準に判断すればよいのでしょうか? どのような場合にインライン化を避けるべきでしょうか?
解決方法は?
関数呼び出しのコストを回避することは、物語の半分に過ぎません。
を行う。
-
使用
inline
の代わりに#define
-
極小
の関数の良い候補です。
inline
: コードが速く、実行ファイルが小さくなる (コードキャッシュに残る可能性が高くなる) - 機能が小さい そして 非常に頻繁に呼び出される
はしないでください。
- 大きな関数:実行ファイルのサイズが大きくなり、呼び出しのオーバーヘッドによる実行の高速化にかかわらず、パフォーマンスが著しく低下します。
- I/Oバインドされているインライン関数
- この関数はあまり使用されません。
- コンストラクタとデストラクタ:空の場合でも、コンパイラはそのためのコードを生成します。
-
ライブラリ開発時のバイナリ互換性の破壊
- 既存の関数をインライン化する
- インライン関数を変更、またはインライン関数を非インライン化:旧バージョンのライブラリは旧実装を呼び出す
ライブラリを開発する場合、将来的に拡張可能なクラスにするために、以下のような工夫が必要です。
- ボディが空の場合でも、ノンインラインの仮想デストラクタを追加しました。
- すべてのコンストラクタを非インライン化
- クラスを値でコピーできない場合を除き、コピー コンストラクタと代入演算子の非インライン実装を記述します。
を覚えておいてください。
inline
キーワードはコンパイラへのヒントです。コンパイラはある関数をインライン化しないことを決定することもあれば
inline
を使用します。私は一般に、関数
inline
(非常に小さな関数を書く場合は別として)。
パフォーマンスについては、(いつものように)アプリケーションのプロファイルを作成し、最終的に
inline
ボトルネックとなる関数を抽出します。
参考文献
- インライン化するかしないか
- [9】インライン関数
- ポリシー/C++とのバイナリ互換性の問題
- GotW #33:インライン
- インライン・レダックス
- Effective C++ - 項目33: インラインを賢く利用する
EDIT: Bjarne Stroustrup, The C++ Programming Language:
<ブロッククオート
関数は、以下のように定義することができます。
inline
. 例えば
inline int fac(int n)
{
return (n < 2) ? 1 : n * fac(n-1);
}
は
inline
の呼び出しに対応するコードを生成するようにコンパイラに指示します。fac()
というのは、一旦関数のコードを書いてから通常の関数呼び出しメカニズムで呼び出すのではなく、インラインで呼び出すからです。賢いコンパイラは、定数720
を呼び出した場合fac(6)
. 相互に再帰的なインライン関数や、入力によって再帰するインライン関数、しないインライン関数などがあり得るため、すべてのインライン関数の呼び出しを保証することは不可能です。inline
関数は実際にインライン化されています。コンパイラの賢さの程度は法律で定めることができないので、あるコンパイラは720
また、別の6 * fac(5)
そして、さらに別のインライン化されていない呼び出しfac(6)
.非常に巧妙なコンパイルやリンクの機能がない場合でもインライン化を可能にするために、インライン関数の定義(宣言だけでなく)がスコープ内になければなりません(9.2節)。例えば
inline
エスペシファイアは関数のセマンティクスに影響を与えません。特に、インライン関数は依然として一意なアドレスを持っており、そのためstatic
変数 (§7.1.2) を持つインライン関数です。
EDIT2: ISO-IEC 14882-1998, 7.1.2 関数指定子
関数宣言(8.3.5、9.3、11.4)に
inline
指定子は、インライン関数を宣言します。インライン指定子は、通常の関数呼び出しメカニズムよりも、呼び出し時に関数本体をインラインで置換することを優先することを実装に示します。しかし,このインライン置換が省略されても,7.1.2 で定義されたインライン関数の他の規則は尊重されなければならない。
関連
-
[解決済み】cc1plus:エラー:g++で認識されないコマンドラインオプション"-std=c++11"
-
[解決済み】デバッグアサーションに失敗しました
-
[解決済み] SQLiteのINSERT/per-secondのパフォーマンスを向上させる
-
[解決済み] 1ビットのセット、クリア、トグルはどのように行うのですか?
-
[解決済み] static_cast, dynamic_cast, const_cast, reinterpret_cast はいつ使うべきですか?
-
[解決済み] C++11では、標準化されたメモリモデルが導入されました。その意味するところは?そして、C++プログラミングにどのような影響を与えるのでしょうか?
-
[解決済み] template "と "typename "キーワードはどこに、なぜ入れなければならないのですか?
-
[解決済み] 関数/メソッドのキーワード 'inline' はいつ書けばよいのですか?
-
[解決済み] noexceptを本当に使うべきはいつですか?
-
[解決済み】画像処理。コカ・コーラ缶」認識のためのアルゴリズム改良
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] テスト
-
[解決済み】C++エラー。アーキテクチャ x86_64 に対して未定義のシンボル
-
[解決済み】Visual Studio 2015で「非標準の構文。'&'を使用してメンバーへのポインターを作成します」エラー
-
[解決済み] 非常に基本的なC++プログラムの問題 - バイナリ式への無効なオペランド
-
[解決済み】ファイルから整数を読み込んで配列に格納する C++ 【クローズド
-
[解決済み】クラスのコンストラクタへの未定義参照、.cppファイルの修正も含む
-
[解決済み】C++ - 適切なデフォルトコンストラクタがない [重複]。
-
[解決済み] 配列のベクトルを扱う正しい方法
-
[解決済み] 関数/メソッドのキーワード 'inline' はいつ書けばよいのですか?
-
[解決済み] なぜC++のインライン関数はヘッダーにあるのですか?