コンパイラは構造体のコピーを最適化し、代わりに配列からメンバーに直接アクセスして、コピーを使用する C コードで必要な値を提供するか、使用する個々のメンバーだけをコピーする場合があります。優れたコンパイラはこれを行います。
ポインターを介して値を格納すると、この最適化が妨げられる可能性があります。たとえば、ルーチンに int へのポインターも含まれているとしますp
。コンパイラがコードINS in = *ins[i]
を処理するとき、次のように「考える」ことができますins[i]
。代わりに、それがコピーであることを覚えておき、in
後で使用するときにメンバーを取得します。」ただし、コードに が含まれている場合、コンパイラが を指していないと推測できない限り*p = 3
、これは変更される可能性があります。(キーワードを使用して、コンパイラがその推論を行うのを助ける方法があります。)ins[i]
p
ins[i]
restrict
要約すると、一見高価に見える操作は、優れたコンパイラによって効率的に実装される可能性があります。安価に見える操作は高価な場合があります (書き込み*p
は大きな最適化を破ります)。一般に、アルゴリズムを明確に表現するコードを記述し、コンパイラに最適化させる必要があります。
コンパイラがこれを最適化する方法を拡張します。次のように書くとします。
for (int i = 0; i < N; i++) {
INS in = *ins[i];
...
}
ここで、「...」内のコードは in.str と in.len にアクセスしますが、INS 構造体に追加する他の 237 のメンバーにはアクセスしません。その後、コンパイラは自由にこのコードを次のように変換できます。
for (int i = 0; i < N; i++) {
char *str = *ins[i].str;
int len = *ins[i].len;
...
}
つまり、見かけ上は INS 構造体のすべてをコピーするステートメントを書いたとしても、コンパイラは実際に必要な部分だけをコピーする必要があります。(実際には、それらの部分をコピーする必要さえありません。ソースコードを直接たどった場合と同じ結果が得られるプログラムを作成するだけで済みます。)