C++インライン関数(C++inline)の詳細

3571 ワード

一般的な関数の欠点:
一つの機能は、関数にカプセル化して呼び出すことと、このコードを直接書くことで、前者は何度も書き換えることを避けることができ、プログラムの体積を減らすことができますが、小さな欠点があり、プログラムに余分な時間のオーバーヘッドをもたらします.関数の実行時に空間を割り当て、パラメータを伝え、戻りアドレスをスタックに入れるなどします.
インライン関数の適用シーン
関数は大量のループで使用され、関数自体の実行時間が短い関数内部に文が何本もない場合、実行時間はもともと非常に短いので、この関数呼び出しによる余分なオーバーヘッドは、関数自体の実行時間に比べて無視できないように見えます.このような関数が1サイクルで数千万回実行されると、関数呼び出しによる時間的なオーバーヘッドにより、プログラムの実行が著しく遅くなる可能性があります.
この問題を解決するために、インライン関数を使用すると、インライン関数は直接関数体のすべてのコードを呼び出し文に挿入します.
コメント:
  • インライン関数を使用すると、最終実行可能プログラムのボリュームが
  • 増加する.
  • は、コンピュータ学科でよく用いられる方法
  • である時間を節約するために、時間と空間を交換するか、または空間消費量を増加させる.
  • は、関数が単純に見える場合があります.例えば、1つまたは2つの文を含むループが1つしかありませんが、このループの実行回数が多く、時間がかかる場合があります.この場合、インライン関数
  • として実装するのは適切ではありません.
  • インライン関数のinlineと関数体定義は一緒に配置され、関数宣言は機能しません(一般的な関数宣言はinlineを追加しません).
  • コンパイラは、関数コードの長さに基づいてインラインするかどうかを決定し、クラスで定義された関数が1行以上ある場合はinlineキーワードを無視します.同時に外部で定義されたインライン関数が10行を超えるとinlineも無視される.この補正規則は、コードの肥大化の問題をある程度低減する
  • inlineはコンパイラにとってただの提案であり、コンパイラは自動的に最適化され、inlineとして定義された関数内に循環/再帰などがある場合、コンパイラは最適化時にインラインを無視します.
  • inlineは分離の宣言と定義を推奨しません.分離するとリンクエラーが発生します.inlineが展開されているため、関数アドレスがなくなり、リンクが見つからない
  • インライン関数はデバッグ可能であり、debugバージョンでは真のインラインが実現されず、releaseでは
  • しか実現されません.
  • クラス宣言のメンバー関数は、自動的にインライン関数に変換されます.(コンストラクション関数とコンストラクション関数は、ベースクラスの関数を呼び出す可能性があるため、簡単にインライン関数に変換することはできません).

  • 詳細:
    関数を使用すると、同じコードを複数回書き換える手間を回避し、実行可能なプログラムの体積を減らすことができますが、プログラムの実行時間のオーバーヘッドも発生します.
    関数呼び出しは、実行時に、まずスタックにパラメータとローカル変数の記憶領域を割り当て、次に実パラメータの値をパラメータにコピーし、次に関数の戻りアドレス(関数実行が終了した後、プログラムがどこに戻って実行を続行すべきかを示すアドレス)をスタックに入れ、最後に関数内部実行にジャンプします.この過程には時間がかかる.
    また,関数がreturn文の戻りを実行する場合,スタックからパラメータと局所変数が占有する記憶領域を回収し,スタックから戻りアドレスを取り出し,そのアドレスにジャンプして実行を継続する必要があり,このプロセスにも時間がかかる.
    要するに,関数呼び出し文を用いることは,関数中のコードを直接書き直すよりも手間が省けるが,プログラム実行時間に余分なオーバーヘッドをもたらす.
    一般的に、このオーバーヘッドは無視できます.しかし、1つの関数の内部にいくつかの文がなく、実行時間がもともと非常に短い場合、この関数呼び出しによる追加のオーバーヘッドは、関数自体が実行される時間に比べて無視できないように見えます.このような関数が1サイクルで数千万回実行されると、関数呼び出しによる時間的なオーバーヘッドにより、プログラムの実行が著しく遅くなる可能性があります.
    特にプログラムの実行効率を重視し、下位システムソフトウェアを記述するのに適した高度なプログラム設計言語として、C++はinlineキーワードで関数呼び出しのオーバーヘッドの問題をよりよく解決した.
    C++では、関数を定義するときに、戻り値タイプの前にinlineキーを付けることができます.次のようになります.
    inline int Max (int a, int b)
    {
         
        if(a >b)
            return a;
        return b;
    }
    

    inlineキーワードを追加した関数を「インライン関数」と呼びます.インライン関数と一般関数の違いは、コンパイラがインライン関数を呼び出す文を処理する場合、その文を関数呼び出しの命令にコンパイルするのではなく、関数体全体のコードを呼び出し文に直接挿入し、関数体全体が呼び出しで書き換えられたようにすることです.
    インライン関数があれば、関数呼び出しを実行する追加のオーバーヘッドを払うことなく、関数を呼び出すようにコードを簡単に繰り返し使用できます.インライン関数を使用すると、最終実行可能プログラムのボリュームが増加することは明らかです.時間を空間と交換したり、空間消費を増やしたりして時間を節約するのがコンピュータ学科でよく使われる方法です.
    インライン関数のコードは、単純で実行が速いいくつかの文にすぎません.1つの関数が複雑であれば、実行時間が関数呼び出しの余分なオーバーヘッドの1万倍になる可能性があります.これをインライン関数として処理した結果、コードボリュームを大幅に増加させる代価を払ったのに、速度を1万分の1に向上させただけで、これは明らかにお得ではありません.
    関数が単純に見える場合があります.たとえば、1つまたは2つの文を含むループが1つしかありませんが、ループの実行回数が多く、時間がかかる場合があります.この場合、インライン関数として実装するのは適切ではありません.
    また、インライン関数の文を呼び出す前に、インライン関数の定義(すなわち、数体全体)がすでに現れている必要があり、インライン関数の宣言だけが現れてはいけないことに注意してください.