假设我在循环中使用了一个数组项,比如
INS *in;
for (int i = 0; i < LEN; i++) {
in = g_ins[i];
if (strcmp(in->mne, str) == 0)
return in;
}
如果我使用索引引用每个引用,编译器会将其优化为上面的内容,或者它是否真的一次又一次地访问每个索引?
for (int i = 0; i < LEN; i++) {
if (strcmp(g_ins[i]->mne, str) == 0)
return g_ins[i];
}
答案 0 :(得分:1)
在很大程度上取决于您的编译器和编译器设置。
一般来说,我不会担心它。
答案 1 :(得分:1)
如果有疑问,你可以尝试一下。例如,将两段代码放入函数中:
INS * f1 (INS *g_ins, const char * str)
{
for (int i = 0; i < LEN; i++) {
INS *in = &g_ins[i];
if (strcmp(in->mne, str) == 0)
return in;
}
return NULL;
}
INS * f2 (INS *g_ins, const char * str)
{
for (int i = 0; i < LEN; i++) {
if (strcmp(g_ins[i].mne, str) == 0)
return &g_ins[i];
}
return NULL;
}
然后使用-O2和-S(例如gcc -std=c99 -O2 -S -Wall code.c -o code.s
)编译它们。 -O2设置优化级别,-S告诉编译器生成汇编代码并停止。
然后查看汇编代码。
即使你不太了解汇编程序,你也应该能够了解这两个函数的相对大小。在函数的情况下,它们编译为相同的代码。
答案 2 :(得分:0)
几乎任何级别的优化,编译器都可能为这两个片段生成相同的代码。事实上,如果没有优化,它可能会在没有显式局部变量的情况下做得更好,因为它不需要显式地存储g_ins[i]
的值;它可能只是放入一个寄存器并使用它两次。
但是,它取决于您使用的编译器以及优化设置。并且这里的任何差异都不太可能是快速程序和慢速程序之间的差异。
答案 3 :(得分:0)
大多数编译器会在正常设置中避免这样的事情。你的变量是在循环之外声明的,编译器不确定在循环之后是否还有INS *的进一步使用。跳过这个阶段除了保存之外不会做太多的优化一些指令,但可能导致后期阶段的输出损坏。