C Language
インライン展開
サーチ…
複数のソースファイルで使用されるインライン関数
頻繁に呼び出される小さな関数の場合、関数呼び出しに関連するオーバーヘッドは、その関数の合計実行時間のかなりの部分になります。パフォーマンスを向上させる方法の1つは、オーバーヘッドを排除することです。
この例では、3つのソースファイルで4つの関数(およびmain()
)を使用します。これらのうち2つ( plusfive()
とtimestwo()
)は、それぞれ "source1.c"と "source2.c"にある他の2つから呼び出されます。 main()
が含まれているので、実際の例があります。
main.c:
#include <stdio.h>
#include <stdlib.h>
#include "headerfile.h"
int main(void) {
int start = 3;
int intermediate = complicated1(start);
printf("First result is %d\n", intermediate);
intermediate = complicated2(start);
printf("Second result is %d\n", intermediate);
return 0;
}
source1.c:
#include <stdio.h>
#include <stdlib.h>
#include "headerfile.h"
int complicated1(int input) {
int tmp = timestwo(input);
tmp = plusfive(tmp);
return tmp;
}
source2.c:
#include <stdio.h>
#include <stdlib.h>
#include "headerfile.h"
int complicated2(int input) {
int tmp = plusfive(input);
tmp = timestwo(tmp);
return tmp;
}
headerfile.h:
#ifndef HEADERFILE_H
#define HEADERFILE_H
int complicated1(int input);
int complicated2(int input);
inline int timestwo(int input) {
return input * 2;
}
inline int plusfive(int input) {
return input + 5;
}
#endif
機能はtimestwo
とplusfive
の両方によって呼び出されるcomplicated1
とcomplicated2
異なる「翻訳単位」、またはソースファイルであり、。このように使用するためには、ヘッダーにそれらを定義する必要があります。
このようにコンパイルすると、gccを仮定します:
cc -O2 -std=c99 -c -o main.o main.c
cc -O2 -std=c99 -c -o source1.o source1.c
cc -O2 -std=c99 -c -o source2.o source2.c
cc main.o source1.o source2.o -o main
最適化をオンにしないとインライン化しないコンパイラーがあるため、-O2最適化オプションを使用します。
inline
キーワードの効果は、対象の関数シンボルがオブジェクトファイルに出力されないことです。それ以外の場合は、最後の行でエラーが発生し、オブジェクトファイルをリンクして最終実行ファイルを作成します。 inline
でないと、同じシンボルが両方の.o
ファイルで定義され、 "複数定義されたシンボル"エラーが発生します。
実際にシンボルが必要な状況では、シンボルがまったく生成されないという欠点があります。それに対処するには2つの可能性があります。 1つ目は、インライン関数のextern
宣言を.c
ファイルの1つに追加することです。 source1.c
次の行を追加します。
extern int timestwo(int input);
extern int plusfive(int input);
他の可能性と機能を定義することであるstatic inline
の代わりにinline
。このメソッドは、最終的に問題の関数のコピーがこのヘッダで生成されたすべてのオブジェクトファイルで生成されるという欠点があります。